我的问题是:我有一个加密的字节文件,如下所示:
[w\x84\x7f@\xc6\xab\xc8
我想用PyCrypto解密,但我发现了一个混乱的bug,如下所示:
此处代码:
^{pr2}$如果我运行这个,它将抛出一个错误:
ValueError Traceback (most recent call last)
<ipython-input-3-4fcf0e8076ca> in <module>()
----> 1 cipher.decrypt(s)
D:\Python\anaconda\lib\site-packages\Crypto\Cipher\blockalgo.py in
decrypt(self, ciphertext)
293 return res
294
--> 295 return self._cipher.decrypt(ciphertext)
296
ValueError: Input strings must be a multiple of 8 in length
我打印s的值:
s = b'[w\\x84\\x7f@\\xc6\\xab\\xc8'
但这是不对的,我需要的是以下结果:
>>> cipher.decrypt(b'[w\x84\x7f@\xc6\xab\xc8')
b'test aaa'
也就是说,我认为我必须将字节文件中的\\\\
替换为\
,但是我没有用正确的方法来做。有人知道怎么解决这个问题吗?在
之所以发生这种情况,是因为文件包含字节字符串的文本表示形式(
[w\x84\x7f@\xc6\xab\xc8
),但实际上不是字节本身。是否正确写入文件:这样你就不会有阅读问题了:
^{pr2}$或者通过
ast.literal_eval
解释保存在文件中的表示,尽管在这种情况下这是不可取的。在底线是:始终知道您使用的是什么类型的字符串(unicode)或字节,请记住,当您在控制台中打印字节时,您看到的是表示(类似于\xa0的内容),而不是字节本身,因为有些字节没有可打印的形式。在
文件中没有双反斜杠。当您查看}(一个反斜杠后跟一个
bytes
对象的repr
时,它显示所有转义的反斜杠,以避免混淆,例如\n
(换行符)和{n
)。在例如:
所以,你问的问题不存在。文件中只有一个反斜杠。在
实际的问题是,您不需要四个字节的反斜杠x、8和4,而需要单字节
b'\x84'
,即chr(0x84)
。但是这四个字节是你文件中的。在所以你的bug存在于你用来创建这个文件的任何代码中。不知何故,不是将字节转储到文件中,而是转储了这些字节的反斜杠转义字符串表示形式。修复它的正确位置是在创建文件的代码中。不写损坏的数据总比写损坏的数据好,然后设法找出如何清除它。在
但是如果为时已晚——例如,如果你用那破代码加密了一堆你不再有权访问的明文,现在你需要尝试恢复它,那么这个转换正好是可逆的。你只需要分两步来完成。在
首先,使用反斜杠转义或更通用的unicode转义编解码器解码字节:
^{pr2}$然后,您可以显式地将每个Unicode字符转换为与相同数字匹配的字节:
…或者,有点老调重弹地依赖Python对拉丁语-1的解释:1
同样,这些反斜杠实际上并不在字符串中,这正是Python表示
bytes
的方式。例如,如果把它放在b
中,hex(b[2])
是0x84
字节\x84
,而不是反斜杠字符的0x5c
。在你的创建代码才是真正的问题:
将字节转换为字符串表示形式,前缀为
b
,前后加引号,每个不能打印的字节都用反斜杠转义,然后去掉b
和引号,然后通过将其写入文本模式文件将整个内容编码为UTF-8。在您只需以二进制模式打开文件并将字节写入其中:
(另外,您不想调用
f.close()
;with
语句已经处理好了。)然后您可以以二进制模式读取文件,并按原样对字节进行解密。在
(或者,如果您真的希望文件是人工可编辑的或其他的,那么您希望选择一种设计为可人工编辑且易于恢复的格式,例如},而不是“Python如何表示
hexlify
或{bytes
用于调试的对象”。)1。对于拉丁语-1中的所有字符,Unicode保证与Latin-1对齐。Python解释这意味着拉丁语-1应该将0-255之间的每个字节编码为0-255,而不仅仅是ISO-8859-1中实际定义的那些。这是有效的,因为ISO-8859-1没有说明如何处理它没有定义的字节,但并不是每个工具都会同意Python。
相关问题 更多 >
编程相关推荐