读取二进制数据(字节顺序)

2 投票
1 回答
777 浏览
提问于 2025-04-17 21:12

我对如何从下面描述的文件中读取二进制数据感到困惑。描述这个数据是如何生成的文档中提到:

有一个“日志文件记录的开始”,格式是这样的:有一条明文消息,后面跟着一个控制字符 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 个回答

0

我觉得你的问题出在你用 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

撰写回答