2012-01-11 33 views
12

Estoy trabajando con Python3.2. Necesito tomar un flujo hexadecimal como entrada y analizarlo a nivel de bit. Así que utilicéConvertir bytes a bits en python

bytes.fromhex(input_str)

para convertir la cadena de bytes reales. Ahora, ¿cómo convierto estos bytes a bits?

+1

Los bytes son bits, solo 8 a la vez;) - La respuesta depende de lo que quiera hacer, por favor sea más específico También la manipulación de bits se realiza principalmente en el nivel de bytes ... –

+0

Quiero representar los bytes en la forma de una cadena de bits para que pueda hacer algo como: campo1 = cadena_bit [0: 1] campo2 = cadena_bit [1:16] y así sucesivamente – user904832

Respuesta

10

¿Qué tal algo como esto?

>>> bin(int('ff', base=16)) 
'0b11111111' 

Esto convertirá la cadena hexadecimal que tiene a un entero y que entero a una cadena en la que cada byte se establece en 0/1 dependiendo del valor de bit del entero.

Como ha señalado un comentario, si usted necesita para deshacerse de la 0b prefijo, puede hacerlo de esta manera:

>>> bin(int('ff', base=16)).lstrip('0b') 
11111111 

o de esta manera:

>>> bin(int('ff', base=16))[2:] 
11111111 
+0

lstrip ('- 0b') # eliminar ceros a la izquierda y signo menos – ahoffer

+0

@ahoffer Gracias por su comentario. He actualizado mi respuesta para que el OP sepa cómo eliminar el prefijo '0b'. – jcollado

+4

Tenga en cuenta que 'lstrip ('0b')' también eliminará, digamos, '00bb' ya que el argumento para' lstrip' es un * conjunto * de caracteres para eliminar. Funcionará bien en este caso, pero prefiero la solución '[2:]' ya que es más explícita. –

14

operaciones son mucho más rápido cuando trabajas en el nivel entero. En particular, convertir a una cadena como se sugiere aquí es realmente lento.

Si solo quiere los bits 7 y 8, use p. Ej.

val = (byte >> 6) & 3 

(esto es:. Cambiar el byte de 6 bits a la derecha - soltándolos Seguidamente, mantenga sólo los últimos dos bits 3 es el número con los dos primeros bits puestos ...)

Estos pueden se puede traducir fácilmente en operaciones simples de CPU que son súper rápidas.

23

Otra manera de hacer esto es mediante el uso del módulo bitstring:

>>> from bitstring import BitArray 
>>> input_str = '0xff' 
>>> c = BitArray(hex=input_str) 
>>> c.bin 
'0b11111111' 

Y si es necesario para despojar a los principales 0b:

>>> c.bin[2:] 
'11111111' 

El módulo bitstring no es un requisito, como La respuesta de jcollado muestra, pero tiene muchos métodos de rendimiento para convertir la entrada en bits y manipularlos. Usted puede encontrar este práctico (o no), por ejemplo:

>>> c.uint 
255 
>>> c.invert() 
>>> c.bin[2:] 
'00000000' 

etc.

+1

+1. Y para la última versión de bitstring (3.0) no necesita quitar el '0b' inicial. –

4

a binario:

bin(byte)[2:].zfill(8) 
+0

No se puede convertir un byte usando bin. – user3467349

3

creo que sería más simple utilización numpy aquí.Por ejemplo, puede leer un archivo como bytes y luego expandirlo en pedazos fácilmente así:

Bytes = numpy.fromfile(filename, dtype = "uint8") 
Bits = numpy.unpackbits(Bytes) 
1

Uso ord al leer bytes de lectura:

byte_binary = bin(ord(f.read(1))) # Add [2:] to remove the "0b" prefix 

O

Uso str.format():

'{:08b}'.format(ord(f.read(1))) 
0

Aquí cómo hacerlo utilizando format()

print "bin_signedDate : ", ''.join(format(x, '08b') for x in bytevector) 

Es importante la 08b. Eso significa que se agregarán un máximo de 8 ceros a la izquierda para completar un byte. Si no especifica esto, el formato tendrá una longitud de bit variable para cada byte convertido.

0

Las otras respuestas aquí proporcionan los bits en orden big-endian ('\x01' convierte '00000001')

En caso de que esté interesado en orden ascendente hacia la izquierda de bits, que es útil en muchos casos, al igual que las representaciones comunes de bignums etc - He aquí un fragmento de eso:

def bits_little_endian_from_bytes(s): 
    return ''.join(bin(ord(x))[2:].rjust(8,'0')[::-1] for x in s) 

Y para la otra dirección:

def bytes_from_bits_little_endian(s): 
    return ''.join(chr(int(s[i:i+8][::-1], 2)) for i in range(0, len(s), 8))