Manipulando datos binarios en Python

Estoy abriendo un archivo binario así:

file = open("test/test.x", 'rb') 

y leyendo en líneas a una lista. Cada línea se ve un poco como:

 '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n' 

Me está costando mucho manipular estos datos. Si bash imprimir cada línea, Python se congela y emite pitidos (creo que hay un código de sonido binario en alguna parte). ¿Cómo hago para usar estos datos de manera segura? ¿Cómo puedo convertir cada número hexadecimal a decimal?

Para imprimirlo, puedes hacer algo como esto:

 print repr(data) 

Para toda la cosa como hexágono:

 print data.encode('hex') 

Para el valor decimal de cada byte:

 print ' '.join([str(ord(a)) for a in data]) 

Para descomprimir enteros binarios, etc. de los datos como si originalmente provinieran de una estructura de estilo C, mire el módulo de estructura .

\xhh es el carácter con valor hexadecimal hh . Otros personajes como . y `~ ‘son caracteres normales.

Iterar en una cadena te da los caracteres que hay en ella, uno a la vez.

ord(c) devolverá un entero que representa el carácter. Por ejemplo, ord('A') == 65 .

Esto imprimirá los números decimales para cada carácter:

 s = '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n' print ' '.join(str(ord(c)) for c in s) 

Como mencionó Theatrus, ord y hex podrían ayudarte. Si desea intentar interpretar algún tipo de datos binarios estructurados en el archivo, el módulo de estructura puede ser útil.

Los datos binarios rara vez se dividen en “líneas” separadas por ‘\ n’. Si es así, tendrá un mecanismo de escape implícito o explícito para distinguir entre ‘\ n’ como terminador de línea y ‘\ n’ como parte de los datos. La lectura de un archivo como líneas a ciegas sin conocimiento del mecanismo de escape no tiene sentido.

Para responder a sus inquietudes específicas:

‘\ x07’ es el carácter ASCII BEL, que originalmente fue para tocar el timbre en una máquina de teletipo.

Puede obtener el valor entero de un byte ‘b’ haciendo ord(b) .

SIN EMBARGO, para procesar correctamente los datos binarios, necesita saber cuál es el diseño . Puede tener enteros con signo y sin signo (de tamaños 1, 2, 4, 8 bytes), números de punto flotante, números decimales de longitudes variables, cadenas de longitud fija, cadenas de longitud variable, etc. La complicación adicional proviene de si los datos se registran En la moda bigendiana o la moda littleendiana. Una vez que sepa todo lo anterior (o tenga muy buenas suposiciones informadas), el módulo de estructura de Python debería poder usarse para todo o la mayor parte de su procesamiento; El módulo ctypes también puede ser útil.

¿El formato de datos tiene un nombre? Si es así, díganos; Es posible que podamos indicarle códigos o documentos.

Usted pregunta “¿Cómo hago para usar estos datos de manera segura?” lo que plantea la pregunta: ¿Para qué quieres usarlo? ¿Qué manipulaciones quieres hacer?

Está intentando imprimir los datos convertidos a caracteres ASCII, que no funcionarán.

Puede utilizar con seguridad cualquier byte de los datos. Si desea imprimirlo como hexadecimal, mire las funciones ord y hex /

¿Estás usando read() o readline() ? Debería estar usando read(n) para leer n bytes; readline() leerá hasta que llegue a una nueva línea, que el archivo binario podría no tener.

En cualquier caso, sin embargo, se le devuelve una cadena de bytes, que pueden ser caracteres imprimibles o no imprimibles, y probablemente no sea muy útil.

Lo que desea es ord() , que convierte una cadena de un byte en el valor entero correspondiente. read() del archivo un byte a la vez y llame a ord() en el resultado, o repita la secuencia completa.

Si está dispuesto a usar NumPy y bitstream , puede hacerlo

 >>> from numpy import * >>> from bitstream import BitStream >>> raw = '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n' >>> stream = BitStream(raw) >>> stream.read(raw, uint8, len(stream) // 8) array([190, 0, 200, 100, 248, 100, 8, 228, 46, 7, 126, 3, 158, 7, 190, 3, 222, 7, 254, 10], dtype=uint8)