Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I convert a python urandom to a string?

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'\x8bz\xaf$\xb6\x93q\xef\x94\x99$\x8c\x1eO\xeb\xed\x03O\xc6L%\xe70\xf9\xd8
\xa4\xac\x01\xe1\xb5\x0bM#\x19\xea+\x81\xdc\xcb\xed7O\xec\xf5\\}\x029\x122
\x8b\xbd\xa9\xca\xb2\x88\r+\x88\xf0\xeaE\x9c'

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.

like image 960
user1876508 Avatar asked Jul 30 '13 22:07

user1876508


People also ask

What does Urandom do in Python?

urandom() method is used to generate a string of size random bytes suitable for cryptographic use or we can say this method generates a string containing random characters. Return Value: This method returns a string which represents random bytes suitable for cryptographic use.

What is B in front of string Python?

The b" notation is used to specify a bytes string in Python. Compared to the regular strings, which have ASCII characters, the bytes string is an array of byte variables where each hexadecimal element has a value between 0 and 255.

What is Bytestring?

A byte string is a fixed-length array of bytes. A byte is an exact integer between 0 and 255 inclusive. A byte string can be mutable or immutable.

Is OS Urandom predictable?

In #26839 os. urandom() was made non-blocking and non-exception-raising on Linux. As a result os. urandom() is no longer a CSPRNG under some conditions as it can and will return predictable random values without any sort of warning or error flag.


5 Answers

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')
like image 55
user1876508 Avatar answered Sep 29 '22 12:09

user1876508


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.

like image 35
Martijn Pieters Avatar answered Sep 29 '22 13:09

Martijn Pieters


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.

like image 30
Rob Watts Avatar answered Sep 29 '22 14:09

Rob Watts


this easy way:

a = str(os.urandom(64))
print(F"the: {a}")
print(type(a))
like image 41
Ahmad Al ALloush Avatar answered Sep 29 '22 14:09

Ahmad Al ALloush


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'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'

>>> 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))
like image 25
Alexander C Avatar answered Sep 29 '22 12:09

Alexander C