Konstruera (python-bibliotek)
Construct är ett Python- bibliotek för konstruktion och dekonstruktion av datastrukturer på ett deklarativt sätt. I detta sammanhang hänvisar konstruktion, eller byggnad, till processen att konvertera ( serialisera ) ett programmatiskt objekt till en binär representation. Dekonstruktion, eller parsning, hänvisar till den motsatta processen att konvertera (deserialisera) binär data till ett programmatiskt objekt. Att vara deklarativ innebär att användarkoden definierar datastrukturen, istället för konventionen att skriva procedurkod för att uppnå målet. Construct kan arbeta sömlöst med datagranularitet på bit- och bytenivå och olika byteordningar .
Att använda deklarativ kod har många fördelar. Till exempel kan samma kod som kan tolka också bygga (symmetrisk), felsökning och testning är mycket enklare (bevisbara i viss mån), att skapa nya konstruktioner är enkelt (omsluta komponenter) och många fler. Om man är bekant med C (programmeringsspråk) kan man tänka på konstruktioner som att gjuta från char *
till struct foo *
och vice versa, snarare än att skriva kod som packar upp data.
Exempel
Följande exempel visar hur en TCP/IP- protokollstack kan definieras med Construct. En del kod utelämnas för korthetens skull och för enkelhetens skull. Observera också att följande kod bara är Python-kod som skapar objekt.
Först, Ethernet -huvudet (lager 2):
ethernet = Struktur ( " destination" / Bytes ( 6 ) , "källa" / Bytes ( 6 ) , " typ" / Enum ( Int16ub , IPv4 = 0x0800 , ARP = 0x0806 , RARP = 0x8035 , X25 = 0x0805 0,8 IPv6 = 0x86DD , ), )
Därefter IP -huvudet (lager 3):
ip = Struct ( "header" / BitStruct ( "version" / Const ( Nibble , 4 ), "header_length" / Nibble , ), "tos" / BitStruct ( "precedence" / Bytes ( 3 ), "minimize_delay" / Flag , "high_throuput" / Flagga , "high_reliability" / Flagga , "minimize_cost" / Flagga , Padding ( 1 ), ), "total_length" / Int16ub , # ... )
Och slutligen, TCP -huvudet (lager 4):
tcp = Struct ( "källa" / Int16ub , "destination" / Int16ub , "seq" / Int32ub , "ack" / Int32ub , # ... )
Definiera nu hierarkin för protokollstacken. Följande kod "binder" varje par av angränsande protokoll till en separat enhet. Varje sådan enhet kommer att "välja" rätt nästa lager baserat på dess inneslutna protokoll.
layer4tcp = Struktur ( tcp , # ... nyttolast ) layer3ip = Struktur ( ip , "nästa" / Switch ( detta . protokoll , { "TCP" : layer4tcp , } ), ) layer2ethernet = Struktur ( ethernet , "nästa" / Switch ( denna . typ , { "IP" : layer3ip , } ), )
Vid denna tidpunkt kan koden analysera infångade TCP/IP-ramar till "paket"-objekt och bygga tillbaka dessa paketobjekt till binär representation.
tcpip_stack = layer2ethernet- paket = tcpip_stack . parse ( b "...raw captured packet..." ) raw_data = tcpip_stack . bygga ( paket )
Hamnar och spin-offs
Perl
Data::ParseBinary är en CPAN- modul som har sitt ursprung som en port av Construct till programmeringsspråket Perl . (se dess huvudsakliga POD-dokument för inspiration). Sedan den första versionen har vissa delar av det ursprungliga API:et föråldrats.
Java
En port till Java är tillgänglig på GitHub . Exempel i Java, Ethernet- huvudet (lager 2):
Konstruera ethernet_header = Struct ( "ethernet_header" , MacAddress ( "destination" ), MacAddress ( "källa " ), Enum ( UBInt16 ( "typ" ), "IPv4" , 0x0800 , "ARP" , 0x0806 , "RARP" , 5 0 ,x "X25" , 0x0805 , "IPX" , 0x8137 , "IPv6" , 0x86DD , "_default_" , Pass ));