2013-07-30 18 views
23

Jeśli zadzwonię do os.urandom (64), otrzymam 64 losowe bajty. W nawiązaniu do Convert bytes to a Python string PróbowałemJak mogę przekonwertować python urandom na ciąg znaków?

a = os.urandom(64) 
a.decode() 
a.decode("utf-8") 

ale dostałem błąd Traceback stwierdzając, że bajty nie są w 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 

z bajtów

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' 

Czy istnieje fullproof metoda dekodowania tych bajtów w jakiś ciąg znaków? Generuję sudo losowych tokenów, aby śledzić powiązane dokumenty w wielu silnikach baz danych.

+0

Odd sposób to zrobić ... Dlaczego nie wystarczy mieć bardziej „centralną” db, który generuje własny identyfikator, który odnosi się do innych identyfikatorów ... ? Lub, zamiast używać 'urandom' - dlaczego nie użyć UUID4 lub podobnego? –

+0

Czy można to również wykorzystać do generowania losowego materiału siewnego? – Pinocchio

+0

Django generuje losową logikę ciągów. https://github.com/django/django/blob/master/django/utils/crypto.py#L51 – bgth

Odpowiedz

33

W Pythonie 3, odpowiedź jest

from base64 import b64encode 
from os import urandom 

random_bytes = urandom(64) 
token = b64encode(random_bytes).decode('utf-8') 
+0

dzięki, działa również na Pythonie 2.7! –

7

Masz losowe bajty; Byłbym bardzo zaskoczony, gdyby kiedykolwiek dało się go dekodować.

Jeśli masz mieć ciąg Unicode, dekodowanie z Latin-1:

a.decode('latin1') 

ponieważ mapuje bajty jeden-na-jeden do odpowiednich punktów kodowych Unicode.

+0

Wydaje się działać za każdym razem. Potrzebuję tylko łańcucha, który zaakceptuje pole char django. – user1876508

+0

Tak; Szkoda, że ​​Django dodał tylko binarne pole w nadchodzącym wydaniu 1.6. –

15

Można użyć kodowania base-64. W tym przypadku:

a = os.urandom(64) 
a.encode('base-64') 

Należy również pamiętać, że używam encode tutaj zamiast decode, jak decode próbuje zabrać go z dowolnym formacie można określić w Unicode. W twoim przykładzie traktujesz losowe bajty tak, jakby tworzyły prawidłowy ciąg znaków utf-8, co rzadko ma miejsce w przypadku losowych bajtów.

+2

Otrzymałem komunikat o błędzie z informacją, że obiekt "bajtów" nie ma atrybutu kodowania. Czy ten kod jest specyficzny dla niektórych wersji Pythona? Używam 3.3 – user1876508

+1

Nie jestem pewien co do python3.x. Używam python2.7 –

+0

@ user1876508 próbowałeś używając 'str (b'hello ', kodowanie)'? Może działać z "base-64" jako kodowaniem. –

Powiązane problemy