我想将我计算的 crc append 到现有的二进制文件中。
例如,crc 为 0x55667788。
我想将 0x55、0x66、0x77 和 0x88 append 到文件末尾。
例如,如果我在 HexEdit 中打开文件,则文件的最后四个字节 将显示 0x55667788。
这是迄今为止我的代码:
fileopen = askopenfilename()
filename = open(fileopen, 'rb+')
filedata = filename.read()
filecrc32 = hex(binascii.crc32(filedata))
filename.seek(0,2)
filename.write(filecrc32)
filename.close()
我收到以下错误:
File "C:\Users\cjackel\openfile.py", line 9, in <module>
filename.write(filecrc32)
TypeError: 'str' does not support the buffer interface
有什么建议吗?
最佳答案
hex
函数返回一个字符串。在本例中,您有一个由 10 个十六进制字符组成的字符串,代表您的 4 字节数字,如下所示:
'0x55667788'
在 Python 2.x 中,您可以将这些不正确的数据写入二进制文件(它将显示为 10 个字节 30 78 35 35 36 36 37 37 38 38
而不是您想要的四个字节,55 66 77 88
)。 Python 3.x 更智能,只允许您将 bytes
(或 bytearray
或类似内容)写入二进制文件,而不是 str
。
这里你想要的不是十六进制字符串,而是实际的字节。
您描述所需字节的方式称为 big-endian order 。在大多数计算机上,“ native ”顺序是相反的小端顺序,这将为您提供 0x88776655
而不是 0x55667788
。
在 Python 3.2+ 中,最简单的方法是 int.to_bytes
方法:
filecrc = binascii.crc32(filedata).to_bytes(4, byteorder='big', signed=False)
(signed=False
并不是真正必要的,因为它是默认值,但这是一个很好的方法,可以明确表明您确实正在处理无符号 32 位整数。)
如果您无法使用早期版本,可以使用 struct
模块:
filecrc = struct.pack('>I', binascii.crc32(filedata))
>
表示大端字节序,I
表示无符号 4 字节整数。所以,这会返回相同的结果。无论哪种情况,您得到的都是 b'\x55\x66\x77\x88'
(或者,正如 Python 所 repr
那样,b'\Ufw\x88'
)。
这个错误有点神秘,因为新手不会知道“缓冲区接口(interface)”是什么(特别是因为 3.x 文档将其称为 Buffer Protocol ,并且它仅记录为 CPython 的 C 的一部分)扩展 API...),但实际上这意味着您需要 bytes-like object 。通常,此错误意味着您只是忘记将字符串编码为 UTF-8 或其他某种编码。但是,当您尝试写入实际的二进制数据而不是编码文本时,会出现同样的错误。
关于python - 使用 Python 将数据字节 append 到二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20621829/