读取二进制数据(字节顺序)
我对如何从下面描述的文件中读取二进制数据感到困惑。描述这个数据是如何生成的文档中提到:
有一个“日志文件记录的开始”,格式是这样的:有一条明文消息,后面跟着一个控制字符 ctrl-Z '0x1a'(在 DOS/Windows 中表示文件结束),ctrl-D '0x04'(在 Unix 中表示文件结束),以及 null '0x00'(按照设计文档的顺序)。
接下来是一个值 0x12345678(长度为 4 字节,用于让任意解码器确定字节存储顺序)。
然后就是数据的主要部分。
我用来读取这个文件的代码:
f = open(filename, 'rb')
while True:
byte = f.read(1)
if byte.encode('hex') == '1a': # ctrl-z
if s[i+1].encode('hex') == '04': # ctrl-D
if s[i+2].encode('hex') == '00': # null
print s[i:i+8].encode('hex')
break
打印结果是 >> 1a04007856341200
可以看到,0x12345678
隐藏在里面。我从研究中了解到,这意味着数据是以“小端”格式存储的。我觉得我现在用的工具让事情变得比我需要的要复杂得多。例如,下面的代码提取了文件创建的年份(YYYY):
i = year_location_in_file # just a pointer
created_year = struct.unpack('<cc', s[i:i+2])
print 'created_year as hex:', created_year
created_year = int(''.join([e for e in created_year][::-1]).encode('hex'), 16)
print 'created year as int:', created_year
打印结果是:
>> 创建年份以十六进制表示: ('\xdd', '\x07')
>> 创建年份以整数表示: 2013
我花了很多时间试图理解所有建议的问题,并尽可能多地阅读我能在谷歌上找到的内容。我希望这些答案能帮助我,也能帮助其他在理解二进制文件中的字节顺序方面挣扎的人。谢谢大家。
编辑:使用 print(repr(open(filename, 'rb').read(600)))
得到的结果是:
....sometext\xd4\xb4\x97\x1a\x04\x00xV4\x12\x00U\x01\.....
- B
1 个回答
我觉得你的问题出在你用 c
作为 struct.unpack
的代码,而不是用一个更大的类型。c
代表字符,只占一个字节(这意味着字节顺序不重要)。相反,你可以用 h
来表示一个占两个字节的短整型,或者用 l
来表示一个占四个字节的长整型(如果你需要无符号值,就用大写字母)。
year_data = b"\x77\x07" # bytes sliced from the binary file
year = struct.unpack("<h", year_data) # unpacked to int in one go