Construct es una biblioteca de Python para la construcción y deconstrucción de estructuras de datos de forma declarativa . En este contexto, la construcción se refiere al proceso de convertir ( serializar ) un objeto programático en una representación binaria.
La deconstrucción, o análisis sintáctico, se refiere al proceso inverso de convertir (deserializar) datos binarios en un objeto programático. Ser declarativo significa que el código del usuario define la estructura de datos, en lugar de la convención de escribir código procedimental para lograr el objetivo. Construct puede funcionar sin problemas con granularidad de datos a nivel de bit y byte , y con diversos ordenamientos de bytes .
Beneficios
El uso de código declarativo ofrece muchas ventajas. Por ejemplo, el mismo código que analiza datos también puede construirlos (simétrico), la depuración y las pruebas son mucho más sencillas (demostrables hasta cierto punto), la creación de nuevas estructuras es fácil (encapsulando componentes) y muchas más. Si se está familiarizado con el lenguaje de programación C , se pueden concebir las estructuras como conversiones de tipo , en lugar de escribir código que desempaquete los datos.char *struct foo *
Ejemplo
El siguiente ejemplo muestra cómo se podría definir una pila de protocolos TCP/IP usando Construct. Se ha omitido parte del código para mayor brevedad y simplicidad. Cabe destacar que el siguiente código es simplemente código Python que crea objetos.
Primero, la cabecera Ethernet (capa 2):
ethernet = Struct ( "destino" / Bytes ( 6 ), "origen" / Bytes ( 6 ), "tipo" / Enum ( Int16ub , IPv4 = 0x0800 , ARP = 0x0806 , RARP = 0x8035 , X25 = 0x0805 , IPX = 0x8137 , IPv6 = 0x86DD , ), )A continuación, la cabecera IP (capa 3):
ip = Struct ( "header" / BitStruct ( "version" / Const ( Nibble , 4 ), "header_length" / Nibble , ), "tos" / BitStruct ( "precedence" / Bytes ( 3 ), "minimize_delay" / Flag , "high_throuput" / Flag , "high_reliability" / Flag , "minimize_cost" / Flag , Padding ( 1 ), ), "total_length" / Int16ub , # ... )Y finalmente, la cabecera TCP (capa 4):
tcp = Struct ( "source" / Int16ub , "destination" / Int16ub , "seq" / Int32ub , "ack" / Int32ub , # ... )Ahora definamos la jerarquía de la pila de protocolos. El siguiente código "vincula" cada par de protocolos adyacentes en una unidad separada. Cada una de estas unidades "seleccionará" la siguiente capa adecuada en función del protocolo que contiene.
capa4tcp = Estructura ( tcp , # ... carga útil )capa3ip = Struct ( ip , "next" / Switch ( this . protocol , { "TCP" : capa4tcp , } ), )capa2ethernet = Struct ( ethernet , "next" / Switch ( this . type , { "IP" : capa3ip , } ), )En este punto, el código puede analizar las tramas TCP/IP capturadas y convertirlas en objetos "paquete", para luego reconstruir estos objetos paquete y convertirlos nuevamente en una representación binaria.
tcpip_stack = layer2ethernet packet = tcpip_stack . parse ( b "...paquete capturado sin procesar..." ) raw_data = tcpip_stack . build ( packet )Puertos y empresas derivadas
Perl
Data::ParseBinary [ 1 ] es un módulo CPAN que se originó como una adaptación de Construct al lenguaje de programación Perl . (Consulte su documento POD principal para conocer su inspiración). Desde la versión inicial, algunas partes de la API original han quedado obsoletas.
Java
Existe una versión para Java disponible en GitHub. [ 2 ] Ejemplos en Java, el encabezado Ethernet (capa 2):
Construct ethernet_header = Struct ( "ethernet_header" , MacAddress ( "destination" ), MacAddress ( "source " ), Enum ( UBInt16 ( "type" ), "IPv4" , 0x0800 , "ARP" , 0x0806 , "RARP" , 0x8035 , "X25" , 0x0805 , "IPX" , 0x8137 , "IPv6" , 0x86DD , "_default_" , Pass ));Véase también
Referencias
Enlaces externos
- Documentación de Construct
- Repositorio de Construct
- Formación en Python
- Bibliotecas de Python (lenguaje de programación)
- generadores de analizadores sintácticos