1 回答
TA贡献1784条经验 获得超9个赞
你的代码解密部分的这个小修改使它对我有用:
textInput = str(input(">>> "))
# encrypted = textInput.encode() #this is incorrect!
encrypted = eval(textInput)
这就是我得到的:
对于加密部分:
>>> test message
b'>xB)\xf1\xc5I\xd6\xce\xfb\xcf\x83\xe2\xc5\x8f\xcfl\xb9\x0f\xa2\x13\xa5\xe1\x03\xf7p\xb3\x9c\xeb\r\xc1"\xf2\x17\x8b\xea\t\xed\xb2xG\xb7\r\xa9\xf8\x03eBD\xdd9>\xbe\xd1O\xe2\x9f\xbb\xf9\xff5\x96l\xea\x17FI\x8d\x02\x05\xea\x1dpM\xbb\x04J\xfc\x0c\\\xfe\x15\x07\xaf \x9e\xc2\xf9M\xa4\x1d$\xc3\x99my\xb6\xc5\xad\x97\xd06\xd2\x08\xd3\xe2\xc8H\xca\xd8\xfd{\xe6\xc6\xa3\x18\xeb\xe6\xcc\xc5\x9a\xc8*\xbb\xc1\x8c\x80,\x1f\r@\x9b\x9d\xc5\x91I\xa8\xc01y\xbc\xa73\xd3\x19;\xef\x8a\xfb\xc2\xc4\x9e\xbe\x8f\xeb\x1d\x12\xbd\xe4<\xa0\xbb\x8d\xef\xee\xa3\x89E\x07"m\x1d\xb0\xf3\xd2:y\xd9\xbd\xef\xdf\xc9\xbb\x1b\xd5\x03\x91\xa4l\x8bS\x9e\x80\x14\x90\x18\xc4\x9e\\?\x8eF\x05\xa1H\x9e:\x0c\x96\x8e\xb3E3\x90\xa2\xa1\xd9\x88\xa0<X\x7f\rIP\x00\xbf\xf6\x15\xfb9tW\x17\x9f\xca\x95\xf6|\xd7\x90\xbcp\xe5\xb5,V\x1b\xe9\x90\xf6\x87 v=6'
现在对于解密部分,我使用输出:
>>> b'>xB)\xf1\xc5I\xd6\xce\xfb\xcf\x83\xe2\xc5\x8f\xcfl\xb9\x0f\xa2\x13\xa5\xe1\x03\xf7p\xb3\x9c\xeb\r\xc1"\xf2\x17\x8b\xea\t\xed\xb2xG\xb7\r\xa9\xf8\x03eBD\xdd9>\xbe\xd1O\xe2\x9f\xbb\xf9\xff5\x96l\xea\x17FI\x8d\x02\x05\xea\x1dpM\xbb\x04J\xfc\x0c\\\xfe\x15\x07\xaf \x9e\xc2\xf9M\xa4\x1d$\xc3\x99my\xb6\xc5\xad\x97\xd06\xd2\x08\xd3\xe2\xc8H\xca\xd8\xfd{\xe6\xc6\xa3\x18\xeb\xe6\xcc\xc5\x9a\xc8*\xbb\xc1\x8c\x80,\x1f\r@\x9b\x9d\xc5\x91I\xa8\xc01y\xbc\xa73\xd3\x19;\xef\x8a\xfb\xc2\xc4\x9e\xbe\x8f\xeb\x1d\x12\xbd\xe4<\xa0\xbb\x8d\xef\xee\xa3\x89E\x07"m\x1d\xb0\xf3\xd2:y\xd9\xbd\xef\xdf\xc9\xbb\x1b\xd5\x03\x91\xa4l\x8bS\x9e\x80\x14\x90\x18\xc4\x9e\\?\x8eF\x05\xa1H\x9e:\x0c\x96\x8e\xb3E3\x90\xa2\xa1\xd9\x88\xa0<X\x7f\rIP\x00\xbf\xf6\x15\xfb9tW\x17\x9f\xca\x95\xf6|\xd7\x90\xbcp\xe5\xb5,V\x1b\xe9\x90\xf6\x87 v=6'
test message
原始代码的问题在于,您将字节字符串的表示形式编写为 unicode 字符串(使用时print(encrypted)),然后在解密代码中将其编码为字节对象,然后将其传递给解密函数。编码此字符串不会产生原始字节字符串encrypted。
这个例子说明了这个问题:
>>> x = bytes(bytearray.fromhex('f3'))
>>> x #A bytes string, similar to encrypt
b'\xf3'
>>> print(x)
b'\xf3'
>>> len(x)
1
>>> str(x) #this is what print(x) writes to stdout
"b'\\xf3'"
>>> print(str(x))
b'\xf3'
>>> len(str(x)) #Note that the lengths are different!
7
>>> x == str(x)
False
>>> str(x).encode() #what you were trying to do
b"b'\\xf3'"
>>> x == str(x).encode()
False
>>> eval(str(x)) #what gets the desired result
b'\xf3'
>>> x == eval(str(x))
True
问题是该print
函数打印对象的表示而不是对象本身。本质上,它通过使用该对象的__repr__
or__str__
方法获取固有不可打印对象的可打印值来实现这一点。
这是文档__str__
:
str(object)
由内置函数调用,format()
并print()
计算对象的“非正式”或可很好打印的字符串表示。返回值必须是字符串对象。. . 内置类型对象调用定义的默认实现object.__repr__()
。
和__repr__
:
由
repr()
内置函数调用以计算对象的“官方”字符串表示。如果可能的话,这应该看起来像一个有效的 Python 表达式,可以用来重新创建一个对象
返回的这个“官方”表示__repr__
允许我eval
在解密代码中使用该函数来解决问题。
TL;DR :复制的输出print(encrypted)
复制encrypted.__str__()
由. 它们不能被编码回(通过使用编码)来创建它们所代表的原始字节字符串。encrypted.__repr__()
utf-8
utf-8
来自stackoverflow用户的这个问题也值得研究,面临同样的问题。如果需要,答案提供了一种将这种表示实际编码回字节对象的方法。值得研究一下,因为eval
应该避免,这是非常不安全的。要使该方法起作用,您必须在对其进行编码之前从字符串中删除前导b'
和尾随。'
textInput
我的最终建议是通过encrypted
使用带有pickle
模块的文件或某种形式的套接字编程在两个程序之间传递整个对象。最好不要在程序之间使用print
和input
传递这样的数据,以避免编码问题。
添加回答
举报