Python: Verketten von Bytes mit einer Zeichenfolge

8

Ich arbeite an einem Python-Projekt in 2.6, das auch zukünftige Unterstützung für python 3 bietet. Ich arbeite gerade an einem Digest-MD5-Algorithmus.

In Python 2.6 ohne diesen Import auszuführen:

%Vor%

Ich kann einen Code wie diesen schreiben:

%Vor%

Ohne Probleme funktioniert meine Authentifizierung einwandfrei. Wenn ich die selbe Codezeile mit den importierten unicode_literals versuche, bekomme ich eine Ausnahme:

UnicodeDecodeError: Der Codecode 'utf8' kann das Byte 0xa8 in Position 0: Unerwartetes Code-Byte

nicht dekodieren

Jetzt bin ich relativ neu bei Python, also bin ich ein bisschen dabei, das herauszufinden. Wenn ich die% s in der Formatierungszeichenfolge als% r ersetze, kann ich die Zeichenfolge verketten, aber die Authentifizierung funktioniert nicht. Die digest-md5-Spezifikation, die ich gelesen habe, besagt, dass der binäre Digest mit 16 Oktetts an diese anderen Strings angehängt werden muss.

Irgendwelche Gedanken?

    
Macdiesel 01.07.2010, 12:02
quelle

2 Antworten

5

Der Grund für das beobachtete Verhalten ist, dass from __future__ import unicode_literals die Art und Weise ändert, wie Python mit Strings arbeitet:

  • In der 2.x-Serie werden Zeichenfolgen ohne das Präfix u als Bytefolgen behandelt, von denen jede im Bereich \ x00- xff (einschließlich) liegen kann. Zeichenfolgen mit dem Präfix u sind UCS-2-codierte Unicode-Sequenzen.
  • In Python 3.x - wie auch in unicode_literals future - sind Zeichenfolgen ohne das Präfix u Unicode-Strings, die in UCS-2 oder UCS-4 codiert sind (abhängig vom Compiler) Flag, das beim Kompilieren von Python verwendet wird). Zeichenfolgen mit dem Präfix b sind Literale für den Datentyp bytes , die den Nicht-Unicode-Zeichenfolgen vor 3.x ziemlich ähnlich sind.

In beiden Python-Versionen müssen Byte-Strings und Unicode-Strings konvertiert werden. Die standardmäßig durchgeführte Konvertierung hängt vom Standardzeichensatz Ihres Systems ab. In Ihrem Fall ist dies UTF-8 . Ohne etwas zu setzen, sollte es ascii sein, das alle Zeichen über \ x7f zurückweist.

Der von hashlib.md5 (...). digest () zurückgegebene Nachrichtenauszug ist eine Byte-Zeichenfolge, und ich nehme an, dass das Ergebnis der gesamten Operation auch eine Byte-Zeichenfolge sein soll. Wenn Sie das wollen, konvertieren Sie die Nonce und Cnonce-Strings in Byte-Strings.:

%Vor%

Alternativ können Sie die vom Aufruf kommende Byte-Zeichenfolge in digest() in eine Unicode-Zeichenfolge konvertieren (nicht empfohlen). Da die unteren 8 Bits von UCS-2 der ISO-8859-1 entsprechen, könnte dies Ihren Anforderungen entsprechen:

%Vor%     
nd. 01.07.2010, 13:08
quelle
1

Das Problem ist, dass "% s:% s:% s" zu einer Unicode-Zeichenfolge wurde, nachdem Sie Unicode-Literale importiert haben. Die Ausgabe des Hash ist eine "normale" Zeichenfolge. Python hat versucht, die reguläre Zeichenkette in eine Unicode-Zeichenkette zu dekodieren, und ist fehlgeschlagen (wie erwartet. Die Hash-Ausgabe soll wie Rauschen aussehen). Ändern Sie Ihren Code wie folgt:

%Vor%

Ich gehe davon aus, dass cnonce und challenge["nonce"] reguläre Zeichenketten sind. Um mehr Kontrolle über ihre Konvertierung in Strings zu haben (falls benötigt), verwenden Sie:

%Vor%     
Tal Weiss 01.07.2010 12:46
quelle

Tags und Links