使用 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:
Get a byte.
Add the first 7 bits of this byte to Size.
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)
我有关于二进制文件结构的说明,我正在尝试构建解析器以从二进制文件中获取信息。在遇到以下情况之前,我做得很好:
Start with a DWORD Size = 0. You're going to reconstruct the size by getting packs of 7 bits:
Get a byte.
Add the first 7 bits of this byte to Size.
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)