2012-03-30 37 views
10

我讀Python中的二進制文件和文件格式的文件說:的Python:從一個字節中提取位

標誌(二進制)含義

1 NNN NNNN表示有是遵循 的一個數據字節,其將被複製爲nnn nnnn(最大127) 次。

0 nnn nnnn表示圖像 有nnn個nnnn個字節(最大127個字節),並且 沒有重複。

Ñ000 0000結束行的字段。表示行 記錄的結束。 n的值可以是零或一。 請注意,行尾字段是必需的,並且它反映在上述行記錄 字段的長度中。

當讀取文件我期待的字節我在返回1 nnn nnnn其中nnn nnnn部分應該是50

我已經能夠做到這一點使用如下:

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

不過的numBytes計算的感覺就像一個廉價的解決方法。

我可以做更多的位數學來完成的numBytes計算?

你會如何處理這個問題?

+0

相關:[使用Python如何讀取字節中的位?](http://stackoverflow.com/q/2576712/4279) – jfs 2016-05-12 14:18:49

回答

7

可以使用從文件字節相與面具脫光領先位。這會給你留下剩餘位的值:

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 

bytes = [0b10101010, 0b01010101, 0b0000000, 0b10000000] 

for byte in bytes: 
    value = byte & VALUE_MASK 
    has_leading_bit = byte & 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 
+0

謝謝。在這種情況下,我也更喜歡二進制數字。 – 2012-03-30 15:31:12

+0

@EvanBorgstrom在Python 3中,你可以編寫:'data = b'\ xaa \ x55 \ x00 \ x80''和'用於數據中的字節:...'。不要使用'字節'名稱,它是內建類型。 – jfs 2016-05-12 14:25:37

9

檢查比特是否設的經典的方法,是用二進制「和」操作,即

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

要檢查中,n ^個位是否被設置,使用兩種力量,即

def is_set(x, n): 
    return x & 2**n != 0 

is_set(10, 1) # 1 because we count from 0th bit 
>>> True 
+0

謝謝,但這並不真正回答我的問題。給定字節= 178,你將如何提取標誌== 1#numbytes == 50? – 2012-03-30 15:18:45

+1

+1:但一個不需要!= 0部分,如果x&0b10應該足夠。 – tom10 2012-03-30 15:21:33

+1

'!= 0'不像'== True'那樣糟糕,但它很接近。 :) – 2012-03-30 15:22:17

0

不知道我給你正確的,但如果我這樣做,這應該做的伎倆:

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

如果我正確讀出你的描述:

if (byte & 0x80) != 0: 
    num_bytes = byte & 0x7F 
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)

相關問題