How can I convert a python urandom to a string?
Question:
If I call os.urandom(64), I am given 64 random bytes. With reference to Convert bytes to a Python string I tried
a = os.urandom(64)
a.decode()
a.decode("utf-8")
but got the traceback error stating that the bytes are not in utf-8.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 0: invalid start byte
with the bytes
b'x8bzxaf$xb6x93qxefx94x99$x8cx1eOxebxedx03Oxc6L%xe70xf9xd8
xa4xacx01xe1xb5x0bM#x19xea+x81xdcxcbxed7Oxecxf5\}x029x122
x8bxbdxa9xcaxb2x88r+x88xf0xeaEx9c'
Is there a fullproof method to decode these bytes into some string representation? I am generating sudo random tokens to keep track of related documents across multiple database engines.
Answers:
You have random bytes; I’d be very surprised if that ever was decodable to a string.
If you have to have a unicode string, decode from Latin-1:
a.decode('latin1')
because it maps bytes one-on-one to corresponding Unicode code points.
You can use base-64 encoding. In this case:
a = os.urandom(64)
a.encode('base-64')
Also note that I’m using encode
here rather than decode
, as decode
is trying to take it from whatever format you specify into unicode. So in your example, you’re treating the random bytes as if they form a valid utf-8
string, which is rarely going to be the case with random bytes.
The code below will work on both Python 2.7 and 3:
from base64 import b64encode
from os import urandom
random_bytes = urandom(64)
token = b64encode(random_bytes).decode('utf-8')
this easy way:
a = str(os.urandom(64))
print(F"the: {a}")
print(type(a))
Are you sure that you need 64 bytes represented as string?
Maybe what you really need is N-bits token?
If so, use secrets. The secrets module provides functions for generating secure tokens, suitable for applications such as password resets, hard-to-guess URLs, and similar.
import secrets
>>> secrets.token_bytes(16)
b'xebrx17D*txaexd4xe3Sxb6xe2xebP1x8b'
>>> secrets.token_hex(16)
'f9bf78b9a18ce6d46a0cd2b0b86df9da'
>>> secrets.token_urlsafe(16)
'Drmhze6EPcv0fN_81Bj-nA'
Or Maybe you need 64 chars length random string? import string
import secrets
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for i in range(64))
If I call os.urandom(64), I am given 64 random bytes. With reference to Convert bytes to a Python string I tried
a = os.urandom(64)
a.decode()
a.decode("utf-8")
but got the traceback error stating that the bytes are not in utf-8.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 0: invalid start byte
with the bytes
b'x8bzxaf$xb6x93qxefx94x99$x8cx1eOxebxedx03Oxc6L%xe70xf9xd8
xa4xacx01xe1xb5x0bM#x19xea+x81xdcxcbxed7Oxecxf5\}x029x122
x8bxbdxa9xcaxb2x88r+x88xf0xeaEx9c'
Is there a fullproof method to decode these bytes into some string representation? I am generating sudo random tokens to keep track of related documents across multiple database engines.
You have random bytes; I’d be very surprised if that ever was decodable to a string.
If you have to have a unicode string, decode from Latin-1:
a.decode('latin1')
because it maps bytes one-on-one to corresponding Unicode code points.
You can use base-64 encoding. In this case:
a = os.urandom(64)
a.encode('base-64')
Also note that I’m using encode
here rather than decode
, as decode
is trying to take it from whatever format you specify into unicode. So in your example, you’re treating the random bytes as if they form a valid utf-8
string, which is rarely going to be the case with random bytes.
The code below will work on both Python 2.7 and 3:
from base64 import b64encode
from os import urandom
random_bytes = urandom(64)
token = b64encode(random_bytes).decode('utf-8')
this easy way:
a = str(os.urandom(64))
print(F"the: {a}")
print(type(a))
Are you sure that you need 64 bytes represented as string?
Maybe what you really need is N-bits token?
If so, use secrets. The secrets module provides functions for generating secure tokens, suitable for applications such as password resets, hard-to-guess URLs, and similar.
import secrets
>>> secrets.token_bytes(16)
b'xebrx17D*txaexd4xe3Sxb6xe2xebP1x8b'
>>> secrets.token_hex(16)
'f9bf78b9a18ce6d46a0cd2b0b86df9da'
>>> secrets.token_urlsafe(16)
'Drmhze6EPcv0fN_81Bj-nA'
Or Maybe you need 64 chars length random string? import string
import secrets
alphabet = string.ascii_letters + string.digits
password = ''.join(secrets.choice(alphabet) for i in range(64))