2012-03-30 25 views
10

estoy leyendo un archivo binario en Python y la documentación para el formato del archivo dice:Python: La extracción de los bits de un byte

bandera (en binario) Significado

1 nnn nnnn Indica que hay es un byte de datos a seguir que debe duplicarse nnn nnnn (máximo 127) veces.

0 nnn nnnn Indica que hay nnn nnnn bytes de imagen datos a seguir (127 bytes máximo) y que no hay duplicaciones.

n 000 0000 Campo de fin de línea. Indica el final de un registro de línea . El valor de n puede ser cero o uno. Tenga en cuenta que se requiere el campo de fin de línea y que se refleja en la longitud del campo de registro de línea mencionado anteriormente.

Al leer el archivo que estoy esperando el byte estoy en volver 1 nnn nnnn donde la parte nnn nnnn debe ser 50.

he sido capaz de hacer esto utilizando la siguiente:

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

Pero el cálculo de numbytes se siente como una solución económica.

¿Puedo hacer más cálculos de bits para realizar el cálculo de numbytes?

¿Cómo te acercarías a esto?

+0

relacionado: [Usando Python ¿Cómo puedo leer los bits en un byte?] (Http://stackoverflow.com/q/2576712/4279) – jfs

Respuesta

7

Puede quitarse el bit inicial usando una máscara AND con un byte de archivo. Eso le dejará con el valor de los bits restantes:

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

puedo encontrar los números binarios fáciles de entender que cuando se hace hexagonal de bits de enmascaramiento.

EDIT: ejemplo un poco más completo para su caso de uso:

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

Gracias. Yo también prefiero los números binarios en este caso. –

+0

@EvanBorgstrom En Python 3, podría escribir: 'data = b '\ xaa \ x55 \ x00 \ x80'' y' for byte in data: ... '. No use el nombre 'bytes', es un tipo incorporado. – jfs

9

El enfoque clásico de comprobar si se ajusta un bit, es utilizar binario "y" operador, es decir

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

Para comprobar, si n^ésimo bit está establecido, utilizar la potencia de dos, es decir

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

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

Gracias, pero eso realmente no responde mi pregunta. Dado byte = 178, ¿cómo extraerías flag == 1 & numbytes == 50? –

+1

+1: pero uno no necesita la parte! = 0, 'si x & 0b10' debería ser suficiente. – tom10

+1

'! = 0' no es tan malo como' == True', pero está cerca. :) –

0

no está seguro te tengo correctamente, pero si lo hiciera, esto debería hacer el truco:

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

Si leo su descripción correcta:

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

Usted puede hacerlo de esta manera:

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

ahí lo tienes:

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

En lugar de int (bin (byte) [3:], 2), puede usar simplemente: int (bin (byte >> 1), 2)

Cuestiones relacionadas