Xor Verschlüsselung / Entschlüsselung einer Datei mit Python 3

Ich muss eine Datei mit xor mit Python 3 verschlüsseln / entschlüsseln, ich habe einen Code, der in Python 2 gut funktioniert, aber wenn man versucht, ihn an Python 3 anzupassen, gibt mir einige Fehler, die ich nicht lösen kann.

Dieser Code funktioniert gut in Python 2.7:

from itertools import cycle def xore(data, key): return ''.join(chr(ord(a) ^ ord(b)) for (a, b) in zip(data, cycle(key))) with open('inputfile.jpg', 'rb') as encry, open('outputfile.jpg', 'wb') as decry: decry.write(xore(encry.read(), 'anykey')) 

Der Fehler beim Versuch, unverändert in Python 3 laufen zu lassen:

 Traceback (most recent call last): File "ask.py", line 8, in <module> decry.write(xore(encry.read(), 'anykey')) File "ask.py", line 5, in xore return ''.join(chr(ord(a) ^ ord(b)) for (a, b) in zip(data, cycle(key))) File "ask.py", line 5, in <genexpr> return ''.join(chr(ord(a) ^ ord(b)) for (a, b) in zip(data, cycle(key))) TypeError: ord() expected string of length 1, but int found 

Bitte, wenn jemand erklären könnte und mir helfen, diesen Code an Python 3 anzupassen.

One Solution collect form web for “Xor Verschlüsselung / Entschlüsselung einer Datei mit Python 3”

a ist schon ein int also musst du den anruf zu ord(a) entfernen:

 def xore(data, key): return ''.join(chr(a ^ ord(b)) for (a, b) in zip(data, cycle(key))) 

Sie werden nicht in der Lage sein, die verbundene Zeichenfolge zu Ihrem Outfile ohne einen .encode("utf-8") zu schreiben, der Ihnen keine nutzbare Ausgabe gibt, also nicht sicher, was Sie tatsächlich versuchen zu erreichen.

Sie können sehen, wenn Sie eine Byte-String indexieren, erhalten Sie ein int in python3:

 n [1]: s = b"foo" In [2]: s[0] Out[2]: 102 # f 

Wo in python2 bekommst du die str / char:

 In [1]: s = b"foo" In [2]: s[0] Out[2]: 'f' 

Iteration oder Aufruf als nächstes gibt Ihnen auch den Integer-Wert:

 In [12]: it = iter(s) In [13]: next(it) Out[13]: 102 In [14]: for ele in s: print(ele) ....: 102 111 111 

In python2 bekommst du nur jeden Charakter. Also in deinem Code, wie du über die Byte-Objekte, die von encry.read() werden, iterieren, encry.read() du die Integer-Werte, also ord(some_int) offensichtlich scheitert.

Es gibt eine gründliche Erklärung Text-versus-binary-Daten, die die Unterschiede zwischen python2 und python3 ein Ausschnitt erklärt:

Als Teil dieser Dichotomie müssen Sie auch vorsichtig sein, um Dateien zu öffnen. Wenn du nicht an Windows gearbeitet hast, gibt es eine Chance, dass du nicht immer die Mühe gemacht hast, den B-Modus beim Öffnen einer Binärdatei hinzuzufügen (zB rb für binäres Lesen). Unter Python 3 sind Binärdateien und Textdateien eindeutig und gegenseitig inkompatibel; Siehe das io-Modul für Details. Daher müssen Sie eine Entscheidung darüber treffen, ob eine Datei für den Binärzugriff verwendet wird (zum Lesen und / oder Schreiben von binären Daten) oder zum Textzugriff (zum Lesen und / oder Schreiben von Textdaten). Du solltest auch io.open () zum Öffnen von Dateien anstelle der eingebauten open () – Funktion verwenden, da das io-Modul von Python 2 bis 3 konsistent ist, während die integrierte open () – Funktion nicht (in Python 3 ist es eigentlich Io.open ()).

Die Konstruktoren von Str und Bytes haben unterschiedliche Semantik für die gleichen Argumente zwischen Python 2 & 3. Das Übergeben einer Integer an Bytes in Python 2 gibt Ihnen die Stringdarstellung der Integer: bytes(3) == '3' . Aber in Python 3 gibt ein Integer-Argument zu Bytes ein Bytes-Objekt, solange die Ganzzahl angegeben ist, gefüllt mit Nullbytes: bytes(3) == b'\x00\x00\x00' . Eine ähnliche Sorge ist notwendig, wenn man ein Bytes-Objekt nach str führt. In Python 2 bekommst du einfach das str(b'3') == b'3' zurück: str(b'3') == b'3' . Aber in Python 3 bekommst du die str(b'3') == "b'3'" : str(b'3') == "b'3'" .

Schließlich erfordert die Indizierung von Binärdaten eine sorgfältige Handhabung (Slicing erfordert keine spezielle Handhabung). In Python 2, b'123'[1] == b'2' während in Python 3 b'123'[1] == 50 . Da Binärdaten einfach eine Sammlung von Binärzahlen sind, gibt Python 3 den Integer-Wert für das Byte zurück, auf das Sie sich registrieren. Aber in Python 2, weil Bytes == str, Indizierung gibt ein Ein-Item-Slice von Bytes. Das sechs Projekt hat eine Funktion namens six.indexbytes (), die eine Ganzzahl wie in Python 3: six.indexbytes (b'123 ', 1) zurückgibt.

Python ist die beste Programmiersprache der Welt.