2013-07-30 14 views
23

Wenn ich os.urandom (64) anrufe, bekomme ich 64 zufällige Bytes. Mit Bezug auf Convert bytes to a Python string habe ich versucht,Wie kann ich einen Python-Urandom in einen String konvertieren?

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

aber bekam den Traceback-Fehler besagen, dass der Bytes nicht 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 

mit dem 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' 

Gibt es eine Methode, um dieses fullproof Bytes in eine String-Darstellung zu entschlüsseln? Ich erzeuge sudo zufällige Token, um die zugehörigen Dokumente über mehrere Datenbank-Engines hinweg zu verfolgen.

+0

Odd Art und Weise, es zu tun ... Warum nicht einfach eine „zentrale“ db haben, der seine eigene ID erzeugt, die an die anderen IDs bezieht sich ... ? Oder, anstatt "Urandom" zu verwenden - warum nicht UUID4 oder ähnliches verwenden? –

+0

Kann dies auch verwendet werden, um einen zufälligen Samen zu erzeugen? – Pinocchio

+0

Djangos generieren zufällige String-Logik. https://github.com/django/django/blob/master/django/utils/crypto.py#L51 – bgth

Antwort

33

In Python 3, die Antwort ist

from base64 import b64encode 
from os import urandom 

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

danke, es funktioniert auch auf Python 2.7! –

7

Sie haben zufällige Bytes; Ich wäre sehr überrascht, wenn das jemals zu einer Saite dekodierbar wäre.

Wenn Sie haben einen Unicode-String, zu dekodieren von Latin-1 haben :

a.decode('latin1') 

weil es Karten Bytes one-on-one zu entsprechenden Unicode-Codepunkten.

+0

Scheint, jedes Mal zu arbeiten. Ich brauche nur eine Zeichenfolge, die das Django-Char-Feld akzeptiert. – user1876508

+0

Ja; Es ist schade, dass Django in der kommenden Version 1.6 nur ein Binärfeld hinzugefügt hat. –

15

Sie können Base-64-Codierung verwenden. In diesem Fall:

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

Beachten Sie auch, dass ich encode hier eher als decode, wie decode versucht, es von nehmen bin mit was auch immer Format, das Sie in Unicode angeben. In Ihrem Beispiel behandeln Sie die zufälligen Bytes so, als ob sie eine gültige utf-8 Zeichenfolge bilden, was bei zufälligen Bytes selten der Fall sein wird.

+2

Ich habe einen Fehler erhalten, der besagt, dass das Objekt 'Bytes' kein Attribut encode hat. Ist dieser Code spezifisch für eine Version von Python? Ich benutze 3.3 – user1876508

+1

Ich bin nicht sicher über python3.x. Ich benutze python2.7 –

+0

@ user1876508 haben Sie versucht, mit 'str (b'hello ', Codierung)'? Es könnte mit 'base-64' als Kodierung funktionieren. –

Verwandte Themen