Pregunta

¿Cuál sería la mejor manera de desembalar una cadena pitón en los campos

Tengo los datos recibidos desde un socket TCP, que está lleno de la siguiente forma, creo que va a estar en una cadena a partir de la función recv toma

Tiene el siguiente formato

uint8 - encabezado
uint8 - Longitud
uint32 - TypeId
uint16 -param1
uint16 -param2
uint16 -param3
uint16 -param4
char [24] - nombre de la cadena
uint32 - suma de comprobación
uint8 - pie de página

(I también tienen que desempaquetar otros paquetes con diferentes formatos a lo anterior)

¿Cómo puedo deshacer estos?

Soy nuevo en el pitón, han hecho un poco de 'C'. Si yo estaba usando 'C' que probablemente utilizar una estructura, esto sería el camino a seguir con Python?

Regards

X

¿Fue útil?

Solución

El módulo de estructura está diseñada para descomprimir datos heterogéneos a una tupla basado en una cadena de formato. Tiene más sentido para descomprimir toda la estructura a la vez en lugar de tratar de sacar un campo a la vez. He aquí un ejemplo:

fields = struct.unpack('!BBI4H20sIB', data)

A continuación, puede acceder a un campo determinado, por ejemplo, el primer campo:

fields[0]

También es posible usar la tupla para inicializar un NamedTuple; mirar el title="documentation para estructura para un ejemplo. NamedTuples sólo están disponibles en Python 2.6+, pero se comportan más como estructuras de Python en la que se puede acceder a los elementos como atributos, por ejemplo fields.header. Por supuesto, también se puede lograr esto con un poco más de trabajo escribiendo una clase para encapsular la información de la tupla ... otra vez, si le interesa. Usted siempre puede indexar en campos directamente, como he mostrado anteriormente.

Otros consejos

struct módulo

Esta es una respuesta a su pregunta-como-un-respuesta:

Desde luego, no puede ser la mejor manera, ya que no funciona. struct.unpack() siempre devuelve una tupla. Para arrancar el único punto en el que la tupla, que tiene que hacer, ya sea field1 = struct.unpack('B',data[0])[0] o field1, = struct.unpack('B',data[0]).

A pesar de que la solución, no es una buena manera: el exceso de mecanografía, la propensión de error de innecesaria [Inicio: Fin]., La ineficiencia de 10 llamadas de función en lugar de uno

A medida que tiene nombres, se puede usar en lugar de campo1 o [0] ... como esto:

(header, length, typeID, param1, param2,
param3, param4, name_string, checksum, footer,
) = struct.unpack("!2B I 4H 24s I B", data)

¿Es esta la mejor manera de hacer esto o hay una mejor manera

Es probable que no habrá cadenas con otros formatos que requieren un esquema de desembalaje diferente

campo1 = struct.unpack ( 'B', los datos [0])
campo2 = struct.unpack ( 'B', los datos [1])
field3 = struct.unpack (datos [2: 6] 'I!')
Field4 = struct.unpack ( '! H', los datos [6: 8])
Field5 = struct.unpack ( '! H', los datos [08:10])
Field6 = struct.unpack ( '! H', los datos [10:12])
Field7 = struct.unpack ( '! H', los datos [12:14])
campo8 = struct.unpack (años 20 ', los datos [14:38])
field9 = struct.unpack ( '! I', los datos [38:42])
field10 = struct.unpack ( 'B', los datos [42])

Regards

Tome una mirada en el módulo de ' estructura '.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top