使用 python 从一个字节中读取位

Reading Bits from a byte with python

我有关于二进制文件结构的说明,我正在尝试构建解析器以从二进制文件中获取信息。在遇到以下情况之前,我做得很好:

Start with a DWORD Size = 0. You're going to reconstruct the size by getting packs of 7 bits:

  1. Get a byte.

  2. Add the first 7 bits of this byte to Size.

  3. Check bit 7 (the last bit) of this byte. If it's on, go back to 1. to process the next byte.

To resume, if Size < 128 then it will occupy only 1 byte, else if Size < 16384 it will occupy only 2 bytes and so on...

我不明白的是“从字节中获取位”和“检查字节的最后一位”是什么意思。 这是我从文件中读取字节的方式:


    from struct import *
    #..... some other blocks of code
    self.standard = {"DWORD":4,"WORD": 2,"BYTE": 1,"TEXT11": 1,"TEXT12": 2}
    st = st = self.standard
    size = 0
    data = unpack("b", f.read(st["BYTE"]))
    #how to get bits???
    if size < 128:
        #use st["TEXT11"]
    elif size < 16384:
        #use st["TEXT12"]

What I'm confused about is what it means to "get bits from a byte"

你可以使用位运算来做到这一点。例如,要获取一个字节的前(低)7 位,请使用

byte & 127

或者,等价地,

byte & 0x7f

byte & 0b1111111

在你的例子中,byte 将是元组 data 的第一个也是唯一的成员。

要获得 last 位,您需要屏蔽该位(使用 &)并将其移位到位(使用 >> ) — 尽管在您的情况下,由于您只需要检查 是否已设置 ,因此转移并不是绝对必要的。

也许混淆与整数的二进制表示有关,例如,如果我们有数字 171 它等同于此二进制配置(1 字节):

val = 0b10101011 # (bit configuration)
print(val) # -> 171 (integer value)

现在您可以使用位掩码只让其中一位通过 (big endian notation):

print(val & 0b00000001) # -> only the first bit pass and then it prints 1
print(val & 0b10000000) # -> only the latest bit pass and then it prints 128
print(val & 0b00000100) # -> it prints 0 because val does not have a 1 to the third position

然后,要检查第七位是否为1,可以执行以下操作:

print((val & 0b01000000) >> 6)
# val    = 0b10101011
#             ^
# mask   = 0b01000000
# result = 0b00000000 -> 0 (integer)
# shift  =    ^123456 -> 0b0

位移位(>> 运算符)允许您获得位掩码的结果。

例如,如果你想要第二位:

print((val & 0b00000010) >> 1)
# val    = 0b10101011
#                  ^
# mask   = 0b00000010
# result = 0b00000010 -> 2 (integer)
# shift  =         ^1 -> 1b0 -> 1 (integer)