使用Python解析字节流中的每个位

时间:2015-03-07 17:26:21

标签: python struct bit-manipulation byte unpack

我有一个二进制文件,它保存字节集以表示某些模块的不同状态标志。以下是4字节结构的示例:

7A 05 00 00

应该是(根据hex-> bin转换器):

0111 1010 0000 0101 0000 0000 0000 0000

现在我无法读取这些字节并按顺序解析它们(它们基本上代表真/假值)。

如果我使用struct.unpack,我必须使用小端解析和无符号整数,如下所示:

>>> with open('the_file.dat', 'rb') as f:
...     b = f.read(4)
>>> struct.unpack('I', b)[0]
1402

如果我将1402转换回整数,我得到完全不同的位,当然不是32位,因为前导零被切断:

>>> "{0:b}".format(1402)
'10101111010'

那么解析这些位的正确方法是什么?我现在有点困惑。

更新:

好的,我发现格式说明符b使用big endian将整数转换为表示位字符串:

>>> struct.unpack('<I', b)[0]
1402
>>> struct.unpack('>I', b)[0]
2047148032
>>> "{0:b}".format(2047148032)
'1111010000001010000000000000000'

前导零(s)仍然缺失,所以是解析这些位以填充前导零的唯一方法,直到我有4个字节(32)的长度,如下所示:

>>> "{0:032b}".format(2047148032)
'01111010000001010000000000000000'

1 个答案:

答案 0 :(得分:0)

要获取十六进制数字字符串的整数值,请尝试使用int进行转换。如果八位字节用空格分隔,您可以使用replace删除它们:

intvalue = int('7A 05 00 00'.replace(' ', ''), base=16)

如果需要表示二进制值的字符串,可以使用bin()生成二进制字符串:

bin(int('7A 05 00 00'.replace(' ', ''), base=16))

收益率:'0b1111010000001010000000000000000'

如果您想从前面删除'0b',可以从字符串中删除前两个字符:

bin(int('7A 05 00 00'.replace(' ', ''), base=16))[2:]

请注意,如果要检查特定标志,则使用字符串形式,而是使用整数形式上的按位运算符来检查特定位。要检查是否设置了位i,您可以使用:

intval & (1 << i) != 0