Python:从字节中提取位

问题描述 投票:20回答:7

我正在读取python中的二进制文件,并且文件格式的文档说:

标记(二进制)表示

1 nnn nnnn表示要跟随一个数据字节可以重复的nnn nnnn(最多127个)次。

0 nnn nnnn表示图像有nnn nnnn个字节后续数据(最大127个字节),并且没有重复。

n 000 0000行尾字段。指示行尾记录。 n的值可以为零或一。请注意,行尾字段是必填字段,它反映在行记录的长度中上面提到的字段。

[读取文件时,我希望我所在的字节返回1 nnn nnnn,其中nnn nnnn部分应为50。

我已经可以使用以下方法做到这一点:

flag = byte >> 7
numbytes = int(bin(byte)[3:], 2)

但是计算numbytes感觉很便宜。

我可以做更多的数学运算来完成对numbytes的计算吗?

您将如何处理?

python byte bit
7个回答
12
投票
您可以使用掩码剥离开头的位,并与文件中的字节相加。剩下的值将留给您:

mask = 0b01111111 byte_from_file = 0b10101010 value = mask & byte_from_file print bin(value) >> 0b101010 print value >> 42

在进行位掩码时,我发现二进制数字比十六进制更容易理解。

编辑:您的用例的稍微完整的示例:

LEADING_BIT_MASK = 0b10000000 VALUE_MASK = 0b01111111 values = [0b10101010, 0b01010101, 0b0000000, 0b10000000] for v in values: value = v & VALUE_MASK has_leading_bit = v & LEADING_BIT_MASK if value == 0: print "EOL" elif has_leading_bit: print "leading one", value elif not has_leading_bit: print "leading zero", value


16
投票
检查位是否被设置的经典方法是使用二进制“和”运算符,即

x = 10 # 1010 in binary if x & 0b10: # explicitly: x & 0b0010 != 0 print('First bit is set')

要检查是否设置了第n ^位,使用2的幂或更好的移位

def is_set(x, n): return x & 2 ** n != 0 # a more bitwise- and performance-friendly version: return x & 1 << n != 0 is_set(10, 1) # 1 i.e. first bit - as the count starts at 0-th bit >>> True


1
投票
如果我正确阅读了您的描述:

if (byte & 0x80) != 0: num_bytes = byte & 0x7F


0
投票
不确定我是否正确地找到了你,但是如果我做到了,这应该可以解决问题:

>>> x = 154 #just an example >>> flag = x >> 1 >>> flag 1 >>> nb = x & 127 >>> nb 26


0
投票
您可以这样操作:

def GetVal(b): # mask off the most significant bit, see if it's set flag = b & 0x80 == 0x80 # then look at the lower 7 bits in the byte. count = b & 0x7f # return a tuple indicating the state of the high bit, and the # remaining integer value without the high bit. return (flag, count) >>> testVal = 50 + 0x80 >>> GetVal(testVal) (True, 50)


0
投票
你去:

class ControlWord(object): """Helper class to deal with control words. Bit setting and checking methods are implemented. """ def __init__(self, value = 0): self.value = int(value) def set_bit(self, bit): self.value |= bit def check_bit(self, bit): return self.value & bit != 0 def clear_bit(self, bit): self.value &= ~bit


0
投票
代替int(bin(byte)[3:],2),您可以简单地使用:int(bin(byte >> 1),2)
© www.soinside.com 2019 - 2024. All rights reserved.