[英]Appending data bytes to binary file with Python
我想将我计算的crc附加到现有的二进制文件中。
例如,crc为0x55667788。
我想将0x55、0x66、0x77和0x88附加到文件末尾。
例如,如果我在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
(或bytes
bytearray
或类似bytes
)写入二进制文件,而不是str
。
您想要的不是十六进制字符串,而是实际的字节数。
描述所需字节的方式称为big-endian order 。 在大多数计算机上,“本机”顺序是相反的,小端顺序,这将为您提供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))
>
表示big-endian, I
表示无符号4字节整数。 因此,这将返回相同的结果。 无论哪种情况,您得到的都是b'\\x55\\x66\\x77\\x88'
(或者,如Python所repr
,为b'\\Ufw\\x88'
)。
该错误有点神秘,因为新手不会知道“缓冲区接口”是什么(特别是因为3.x文档将其称为Buffer Protocol ,并且仅作为CPython C扩展API的一部分进行了记录……) ,但实际上这意味着您需要一个类似字节的对象 。 通常,此错误表示您只是忘记将字符串编码为UTF-8或其他某种编码。 但是,当您尝试编写实际的二进制数据而不是编码的文本时,这是相同的错误。
您需要序列化数据。 序列化是从整数中获取相关字节的过程。 在您的情况下,您的CRC是一个4字节的数字。 可以将单个4个字节检索到列表,如下所示:
serialized_crc = [(filecrc32 >> 24) & 0xFF,(filecrc32 >> 16) & 0xFF,
(filecrc32 >> 8) & 0xFF,filecrc32 & 0xFF]
然后可以通过转换为字节数组,将CRC写入文件,如下所示:
filename.write(bytearray(serialized_crc))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.