To generate a random alphanumeric string using the system's RNG (/dev/urandom
) in Python, you should probably better use random.SystemRandom
:
#!/usr/bin/env python3
import random, string
RNG = random.SystemRandom() # Random Number Generator
characters = string.ascii_letters + string.digits # allowed characters
# build a string by choosing a random character from `characters` 6 times:
s = "".join(RNG.choice(characters) for n in range(6))
print(s)
The method above allows you to exactly specify which characters are allowed and guarantees that your output string has exactly the desired length.
I decided for string.ascii_letters + string.digits
in this example, which results in abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
.
However, you could also use your own small script (or directly read 6 bytes from /dev/urandom
using the command head -c 6 /dev/urandom
) and filter the output to only show alphanumeric characters using tr
:
python3 your_script.py | tr -cd '[:alnum:]' ; echo
head -c 6 /dev/urandom | tr -cd '[:alnum:]' ; echo
The tr
command deletes (-d
) all characters that are not (-c
= complement) in the specified character set '[:alnum:]'
which is a special shorthand for all alphanumeric characters.
The echo
in the end simply produces a line break.
The disadvantage of this is that your output string has an undefined length, because you can't know how many valid characters there will be in the output.
However, if you directly read from /dev/urandom
without Python, you can invert the pipe order like below to keep filtering random bytes until the output has the desired length:
tr -cd '[:alnum:]' < /dev/urandom | head -c 6 ; echo
Alternatively, you can also turn any binary data into readable characters by simply encoding it in base64
, which is a character set of a-z
, A-Z
, 0-9
, /
and +
:
python3 your_script.py | base64
head -c 6 /dev/urandom | base64
Note that the length of a base64
encoded string is always bigger than the length of the original data in bytes. The base64
output will also always end with ==
.
locale
. Add both to your question.