我最近开始使用 Python 解析二进制数据,但对 Python 处理“字节”项的方式感到困惑。举个例子以下口译对话:
>>> f = open('somefile.gz', 'rb')
>>> f
<open file 'textfile.gz', mode 'rb' at 0xb77f4d88>
>>> bytes = f.read()
>>> bytes[0]
'\x1f'
>>> len(bytes[0])
1
>>> int(bytes[0]) <---- calling __str__ automatically on bytes[0] ?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '\x1f'
上面的 session 显示 bytes[0] 的大小为 1 个字节,但 __str__
表示是十六进制的。不用担心,但是当我尝试将 bytes[0] 视为单个字节时,我会遇到奇怪的行为。
如果我想根据某些规范解析/解释二进制流,其中规范包括十六进制、二进制和十进制的表示形式,我将如何去做。
例如将是“前两个字节是 \xbeef
,下一个是十进制 8
,后跟一个压缩位字段,其中字节的 8 位中的每一位都代表一些标志?我我猜有一些模块可以使这项任务变得简单,但我想从头开始。
我看到了对 struct
模块的引用,但是如果不引入新模块就无法检查直接读取的字节吗?像 bytes[0] == 0xbeef
这样的东西?
有人可以帮助我了解人们通常如何使用 Python 解析符合规范的二进制数据吗?谢谢。
最佳答案
您使用的是 Python 2.x。在 Python 3.0 之前,读取文件,即使是二进制文件,也会返回一个字符串。你所说的“字节”对象实际上是一个字符串。像使用“bytes[0]”一样对字符串进行索引只会返回一个 1 个字符的字符串。
struct 模块可能最适合你想要的东西,但如果你真的想要,你可以在没有它的情况下做你要求的事情:
“像 bytes[0] == 0xbeef 之类的东西?”
这行不通,因为 0xbeef 是一个双字节序列,但 bytes[0] 只是一个字节。您可以这样做:
bytes[0:2] == b'\xbe\xef'
在 Python 3.x 中,事情会更像您期望的那样工作。读取二进制文件会返回一个 bytes
对象,该对象的行为类似于 1 字节无符号整数序列,而不是字符串。
关于python - 对 Python 中的字节感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9241042/