Good morning people! I've been trying to convert this code written in Python 2 to Python 3.It's a simple function to encrypt strings using XOR. What I have so far:
import binascii
def encrypt(content: str, key: str) -> str:
key_id = 0
xored = ""
for c in content:
xored += chr(ord(key[key_id % len(key)]) ^ ord(c))
key_id += 1
return binascii.hexlify(xored.encode())
def decrypt(content: str, key: str) -> str:
key_id = 0
xored = ""
for c in binascii.unhexlify(content):
xored += chr(ord(key[key_id % len(key)]) ^ ord(c))
key_id += 1
return binascii.hexlify(xored.encode())
The code in Python 2 works perfectly, but when testing the code above (in Python 3), I'm having problems decoding messages. (The encrypt() function seems to be working perfectly.) The following error happens:
>>> encrypt("foo", "123")
b'575d5c'
>>> decrypt(b"575d5c", "123")
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
decrypt(b"575d5c", "123")
File "/home/user/Code/Python/xorcrypt.py", line 15, in decrypt
xored += chr(ord(key[key_id % len(key)]) ^ ord(c))
TypeError: ord() expected string of length 1, but int found
I checked both documentation, but couldn't identify any difference in versions: ord() in Python 2 and ord() in Python 3. In addition, I searched other sources, but I didn't find any mention of the problem:
Porting Python 2 Code to Python 3
Am I looking at the correct spot? Or would the ord() function not be the problem in this case? Thank you very much in advance!
The difference is not in ord()
but in binascii.unhexlify()
. In Python 2 it returns a string and if you index into that string you get a string of length 1, that you can call ord()
on. But in Python 3 it returns a bytes
and if you index into that, you get a small integer that you can't call ord()
on, and don't need to.