Reputation: 3374
I need a random string that I can write down to use for salt in a hash function. I can generate some random bytes and see them as hex:
import os, binascii
print(binascii.b2a_hex(os.urandom(32)))
b'76449cd6134d64353122102fcb512d1eae1bd8437202b6e06e91a422ce9e386b' # 64 chars
Great, but how do I convert these bytes directly to a string i.e. not necessarily printable, but exactly 32 characters? The hash function requires a string, not a "bytes" type with a maximum length of 32.
I'm not sure how to do the encoding in Python, but I guess I need something similar to the way an old 8-bit computer or a C program would turn a byte into a character (ASCII or other).
This is for the salt input of Django's make_password function.
Upvotes: 0
Views: 784
Reputation: 5520
You could use chr
and join them:
>>> s = ''.join(map(chr, os.urandom(32)))
>>> print(len(s), s)
32 ^Ô¸ÒÜì<ù³B_¶t¶Ùj)"×Ï‚ž™Të$)
Or decode
with let's say latin1:
>>> s = os.urandom(32).decode('latin1')
>>> print(len(s), s)
32 ùLÖ]ù²ì¥Ý.b#AÎ+Ûê+9'Za37
If you do need to go through such a hex string of length 64, just unhex it first:
>>> b = b'76449cd6134d64353122102fcb512d1eae1bd8437202b6e06e91a422ce9e386b'
>>> s = binascii.a2b_hex(b).decode('latin1')
>>> print(len(s), s)
32 vDÖMd51"/ËQ-®ØCr¶àn¤"Î8k
Or starting from random 32 bytes, hex them for show and decode them (without hex+unhex) for use:
>>> b = os.urandom(32)
>>> binascii.b2a_hex(b)
b'5751b7bfe1a3ea50c9f8143d64f4ce07a05a21805c976536147114dab27ee08c'
>>> s = b.decode('latin1')
>>> print(len(s), s)
32 WQ·¿á£êPÉø=dôÎ Z!\e6qÚ²~à
Upvotes: 1