简体   繁体   中英

How to convert bytes to a string of the same length in Python (1 character for each byte)?

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 ie 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.

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Ú²~à

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM