看起来你需要做的是将消息中的每个字符与密钥中的相应字符进行异或。但是,要做到这一点,您需要使用ord和chr进行一些相互转换,因为您只能编号而不是字符串:
>>> encrypted = [ chr(ord(a) ^ ord(b)) for (a,b) in zip(var, key) ]
>>> encrypted
['\x1b', '\x10', '\x1c', '\t', '\x1d']
>>> decrypted = [ chr(ord(a) ^ ord(b)) for (a,b) in zip(encrypted, key) ]
>>> decrypted
['h', 'e', 'l', 'l', 'o']
>>> "".join(decrypted)
'hello'请注意,binascii.a2b_qp("hello")只是将字符串转换为另一个字符串(尽管可能使用不同的编码)。
您的方法和我上面的代码只有在密钥至少与消息一样长时才会起作用。但是,如果需要,您可以使用itertools.cycle轻松重复该键:
>>> from itertools import cycle
>>> var="hello"
>>> key="xy"
>>> encrypted = [ chr(ord(a) ^ ord(b)) for (a,b) in zip(var, cycle(key)) ]
>>> encrypted
['\x10', '\x1c', '\x14', '\x15', '\x17']
>>> decrypted = [ chr(ord(a) ^ ord(b)) for (a,b) in zip(encrypted, cycle(key)) ]
>>> "".join(decrypted)
'hello'为了解决unicode /多字节字符的问题(在下面的注释中提出),可以将字符串(和键)转换为字节,将它们压缩在一起,然后执行XOR,如:
>>> var=u"hello\u2764"
>>> var
'hello❤'
>>> encrypted = [ a ^ b for (a,b) in zip(bytes(var, 'utf-8'),cycle(bytes(key, 'utf-8'))) ]
>>> encrypted
[27, 16, 28, 9, 29, 145, 248, 199]
>>> decrypted = [ a ^ b for (a,b) in zip(bytes(encrypted), cycle(bytes(key, 'utf-8'))) ]
>>> decrypted
[104, 101, 108, 108, 111, 226, 157, 164]
>>> bytes(decrypted)
b'hello\xe2\x9d\xa4'
>>> bytes(decrypted).decode()
'hello❤'