convert - bytes to string python
Convertir bytes a bits en python (9)
¿Qué tal algo como esto?
>>> bin(int(''ff'', base=16))
''0b11111111''
Esto convertirá la cadena hexadecimal que tiene en un entero y ese entero en una cadena en la que cada byte se establece en 0/1 dependiendo del valor de bits del entero.
Como lo señala un comentario, si necesita deshacerse del prefijo 0b
, puede hacerlo de esta manera:
>>> bin(int(''ff'', base=16)).lstrip(''0b'')
11111111
o de esta manera:
>>> bin(int(''ff'', base=16))[2:]
11111111
Estoy trabajando con Python3.2. Necesito tomar un flujo hexadecimal como entrada y analizarlo a nivel de bits. Asi que utilicé
bytes.fromhex(input_str)
para convertir la cadena a bytes reales. Ahora, ¿cómo convierto estos bytes a bits?
A binario
bin(byte)[2:].zfill(8)
Aquí cómo hacerlo usando format()
print "bin_signedDate : ", ''''.join(format(x, ''08b'') for x in bytevector)
Es importante el 08b . Eso significa que será un máximo de 8 ceros iniciales que se agregarán para completar un byte. Si no especifica esto, el formato solo tendrá una longitud de bit variable para cada byte convertido.
Creo que lo más sencillo sería usar numpy
aquí. Por ejemplo, puede leer un archivo como bytes y luego expandirlo a bits de esta manera:
Bytes = numpy.fromfile(filename, dtype = "uint8")
Bits = numpy.unpackbits(Bytes)
Las operaciones son mucho más rápidas cuando se trabaja en el nivel entero. En particular, la conversión a una cadena como se sugiere aquí es realmente lenta.
Si quiere solo los bits 7 y 8, use por ejemplo
val = (byte >> 6) & 3
(esto es: desplace los bytes del bit 6 a la derecha, soltándolos. Luego, mantenga solo los dos últimos bits 3
es el número con los dos primeros bits establecidos ...)
Estos pueden ser fácilmente traducidos en simples operaciones de CPU que son súper rápidas.
Las otras respuestas aquí proporcionan los bits en orden big-endian ( ''/x01''
convierte en ''00000001''
)
En caso de que esté interesado en el orden de bits little-endian, que es útil en muchos casos, como representaciones comunes de bignums, etc. - aquí hay un fragmento de esto:
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))
Otra forma de hacerlo es mediante el módulo de bitstring
:
>>> from bitstring import BitArray
>>> input_str = ''0xff''
>>> c = BitArray(hex=input_str)
>>> c.bin
''0b11111111''
Y si necesitas quitar el 0b
principal:
>>> c.bin[2:]
''11111111''
El módulo de bitstring
no es un requisito, como muestra la respuesta de jcollado , pero tiene muchos métodos eficaces para convertir la entrada en bits y manipularlos. Puede encontrar esto útil (o no), por ejemplo:
>>> c.uint
255
>>> c.invert()
>>> c.bin[2:]
''00000000''
etc.
Use ord
al leer bytes de lectura:
byte_binary = bin(ord(f.read(1))) # Add [2:] to remove the "0b" prefix
O
Utilizando str.format()
:
''{:08b}''.format(ord(f.read(1)))
usando la sintaxis de cadena de formato python
>>> mybyte = bytes.fromhex("0F") # create my byte using a hex string
>>> binary_string = "{:08b}".format(int(mybyte.hex(),16))
>>> print(binary_string)
00001111
La segunda línea es donde ocurre la magia. Todos los objetos de bytes tienen una función .hex()
, que devuelve una cadena hexadecimal. Usando esta cadena hexadecimal, la convertimos a un entero, diciéndole a la función int()
que es una cadena base 16 (porque hex es base 16). Luego aplicamos el formato a ese entero para que se muestre como una cadena binaria. El {:08b}
es donde ocurre la verdadera magia. Está utilizando la especificación de formato Mini-Language format_spec
. Específicamente, utiliza el width
y las partes de type
de la sintaxis de format_spec. Los 8
conjuntos de width
a 8, que es cómo obtenemos el buen relleno 0000, y la b
establece el tipo en binario.
Prefiero este método sobre el método bin()
porque usar una cadena de formato ofrece mucha más flexibilidad.