Konstrukcja (biblioteka Pythona)

Construct to biblioteka Pythona do konstrukcji i dekonstrukcji struktur danych w sposób deklaratywny . W tym kontekście konstrukcja lub budowa odnosi się do procesu konwersji ( serializacji ) obiektu programistycznego na reprezentację binarną. Dekonstrukcja lub parsowanie odnosi się do przeciwnego procesu konwersji (deserializacji) danych binarnych na obiekt programistyczny. Bycie deklaratywnym oznacza, że ​​kod użytkownika definiuje strukturę danych, zamiast konwencji pisania kodu proceduralnego w celu osiągnięcia celu. Construct może bezproblemowo pracować z szczegółowością danych na poziomie bitów i bajtów oraz różnymi porządkowaniami bajtów .

Używanie kodu deklaratywnego ma wiele zalet. Na przykład ten sam kod, który można analizować, można również budować (symetryczny), debugowanie i testowanie jest znacznie prostsze (do pewnego stopnia możliwe do udowodnienia), tworzenie nowych konstrukcji jest łatwe (zawijanie komponentów) i wiele innych. Jeśli ktoś jest zaznajomiony z C (językiem programowania) , może myśleć o konstrukcjach jako rzutowaniu z char * na struct foo * i odwrotnie, zamiast pisania kodu, który rozpakowuje dane.

Przykład

Poniższy przykład pokazuje, jak można zdefiniować stos protokołów TCP/IP przy użyciu konstrukcji. Część kodu została pominięta ze względu na zwięzłość i prostotę. Zauważ też, że poniższy kod to tylko kod Pythona, który tworzy obiekty.

Najpierw nagłówek Ethernet (warstwa 2):

   
      
      
      
        
        
        
        
        
        
    
  ethernet  =  Struct  (  „miejsce docelowe”  /  Bajty  (  6  ),  „źródło”  /  Bajty  (  6  ),  „typ”  /  Enum  (  Int16ub  ,  IPv4  =  0x0800  ,  ARP  =  0x0806  ,  RARP  =  0x8035  ,  X25  =  0x0805  ,  IPX  =  0x8137  ,  IPv6  =  0x86DD  ,  ),  ) 

Następnie nagłówek IP (warstwa 3):

   
      
           
          
    
      
          
          
          
          
          
        
    
      
    
  ip  =  Struct  (  "header"  /  BitStruct  (  "version"  /  Const  (  Nibble  ,  4  ),  "header_length"  /  Nibble  ,  ),  "tos"  /  BitStruct  (  "precedence"  /  Bytes  (  3  ),  "minimalizuj_opóźnienie"  /  Flaga  ,  "high_throuput"  /  Flaga  ,  "high_reliability"  /  Flaga  ,  "minimize_cost"  /  Flaga  ,  Padding  (  1  ),  ),  "całkowita_długość"  /  Int16ub  ,  # ...  ) 

I wreszcie nagłówek TCP (warstwa 4):

   
      
      
      
      
    
  tcp  =  Struct  (  "źródło"  /  Int16ub  ,  "miejsce docelowe"  /  Int16ub  ,  "seq"  /  Int32ub  ,  "ack"  /  Int32ub  ,  # ...  ) 

Teraz zdefiniuj hierarchię stosu protokołów. Poniższy kod „wiąże” każdą parę sąsiednich protokołów w oddzielną jednostkę. Każda taka jednostka „wybierze” odpowiednią następną warstwę na podstawie zawartego w niej protokołu.

   
    
    
 

   
    
      
        
              
        
    
 

   
    
      
        
              
        
    
  layer4tcp  =  Struct  (  tcp  ,  # ... payload  )  layer3ip  =  Struct  (  ip  ,  "next"  /  Switch  (  this  .  protocol  ,  {  "TCP"  :  layer4tcp  ,  }  ),  )  layer2ethernet  =  Struct  (  ethernet  ,  "next"  /  Switch  (  ten  .  typ  ,  {  "IP"  :  layer3ip  ,  }  ),  ) 

W tym momencie kod może analizować przechwycone ramki TCP/IP w obiekty „pakietowe” i budować te obiekty pakietowe z powrotem w postaci binarnej.

   
   
    tcpip_stack  =  pakiet  Layer2Ethernet  =  tcpip_stack  .  parse  (  b  "...surowy przechwycony pakiet..."  )  raw_data  =  tcpip_stack  .  kompilacja  (  pakiet  ) 

Porty i spin-offy

Perl

Data::ParseBinary to moduł CPAN , który powstał jako port Construct do języka programowania Perl . (zobacz jego główny dokument POD, aby znaleźć inspirację). Od pierwszej wersji niektóre części oryginalnego interfejsu API zostały wycofane.

Jawa

Port do Javy jest dostępny na GitHub . Przykłady w Javie, Ethernet (warstwa 2):

    
      
      
      
            
             
            
             
             
            
            
    Construct  ethernet_header  =  Struct  (  "ethernet_header"  ,  MacAddress  (  "miejsce docelowe"  ),  MacAddress  (  "źródło"  ),  Enum  (  UBInt16  (  "typ"  ),  "IPv4"  ,  0x0800  ,  "ARP"  ,  0x0806  ,  "RARP"  ,  0x8035  ,  "X25"  ,  0x0805  ,  "IPX"  ,  0x8137  ,  "IPv6"  ,  0x86DD  ,  "_default_"  ,  pass  )); 

Linki zewnętrzne