2014-04-27 28 views
5

Mit Blick auf Kismet Quellcode in packet_ieee80211.h dieconvert c Enum bitfield Python

enum crypt_type { 
    crypt_none = 0, 
crypt_unknown = 1, 
crypt_wep = (1 << 1), 
crypt_layer3 = (1 << 2), 
// Derived from WPA headers 
crypt_wep40 = (1 << 3), 
crypt_wep104 = (1 << 4), 
crypt_tkip = (1 << 5), 
crypt_wpa = (1 << 6), 
crypt_psk = (1 << 7), 
crypt_aes_ocb = (1 << 8), 
crypt_aes_ccm = (1 << 9), 
//WPA Migration Mode 
crypt_wpa_migmode = (1 << 19), 
// Derived from data traffic 
crypt_leap = (1 << 10), 
crypt_ttls = (1 << 11), 
crypt_tls = (1 << 12), 
crypt_peap = (1 << 13), 
crypt_isakmp = (1 << 14), 
    crypt_pptp = (1 << 15), 
crypt_fortress = (1 << 16), 
crypt_keyguard = (1 << 17), 
crypt_unknown_nonwep = (1 << 18), 
}; 

ich diese Bits als Verschiebung verstehen Abschnitt ist, aber das ist es. Angenommen, ich habe den int-706, wie kann ich diese Nummer brechen in die cryptset wie oben dh definiert, wie kann ich extrahieren, die Krypten verwendet werden, geben 706 besonders portiert Python

Dank

Antwort

3

Aruisdante Antwort ist sehr gut, ich wollte nur auf die Antwort erweitern, wenn Sie eine Python vorherige bis 3,4 verwenden, da es does exist a backport auf PyPI:

from enum import IntEnum 

class Crypt(IntEnum): 
    none = 0 
    unknown = 1 
    wep = (1 << 1) 
    layer3 = (1 << 2) 
    # Derived from WPA headers 
    wep40 = (1 << 3) 
    wep104 = (1 << 4) 
    tkip = (1 << 5) 
    wpa = (1 << 6) 
    psk = (1 << 7) 
    aes_ocb = (1 << 8) 
    aes_ccm = (1 << 9) 
    # WPA Migration Mode 
    wpa_migmode = (1 << 19) 
    # Derived from data traffic 
    leap = (1 << 10) 
    ttls = (1 << 11) 
    tls = (1 << 12) 
    peap = (1 << 13) 
    isakmp = (1 << 14) 
    pptp = (1 << 15) 
    fortress = (1 << 16) 
    keyguard = (1 << 17) 
    unknown_nonwep = (1 << 18) 

    @classmethod 
    def find_crypts(cls, magic_number): 
     crypts = [] 
     for mask in cls: 
      if magic_number & mask == mask: 
       crypts.append(mask) 
     if len(crypts) > 1: 
      # remove false positive of none 
      crypts = crypts[1:] 
     return crypts 

print Crypt.find_crypts(0) 
[<Crypt.none: 0>] 
print Crypt.find_crypts(706) 
[<Crypt.wep: 2>, <Crypt.wpa: 64>, <Crypt.psk: 128>, <Crypt.aes_ccm: 512>] 
8

Also, was haben Sie zu hier zu verstehen ist, dass diese Enum eine Reihe von bitmasks definiert. In diesem Fall enthält jeder dieser Enumerationswerte im Binärformat nur einen einzigen 1. Zum Beispiel

crypt_wep = (1 << 1) = 0b10 
crypt_wpa = (1 << 6) = 0b1000000 

Und so weiter. die bitshift Operator ist nur eine einfache Möglichkeit, darzustellen ‚ich die n-te + 1 binary digit wollen die Fahne sein‘

Auf diese Weise können wir bitweise or ein Bündel von diesen Werten zusammen und erhalten eine magische Zahl, dass beschreibt eine Kombination dieser Crypt-Werte eindeutig als Bit-Flags. Um zu testen, ob eine magische Zahl einen Wert enthält, können wir einfach and es mit dem Wert, den wir wünschen bitweise

magic_number = crypt_wep | crypt_wpa 
has_wep  = (magic_number & crypt_wep) == crypt_wep 
has_wpa  = (magic_number & crypt_wpa) == crypt_wpa 

has_wep und has_wpa testen true, wenn und nur wenn magic_number diese Bit-Flags enthalten.

Also schauen wir uns die Nummer 706, die in binär ist 0b1011000010. Wir können uns das ansehen und sofort sehen, dass es mit crypt_wep, crypt_wpa, und crypt_aes_ccm aufgebaut worden sein muss, weil die richtigen Bits für diese Werte gesetzt sind.

So, wie zu Python portieren? Nun, Python hat enums genau wie C/C++, wenn Sie in Python 3.4 oder höher sind. So können Sie einfach die gleiche Enum-Tabelle in Python erstellen und die gleichen bitweisen Tests anwenden, um zu bestimmen, was Ihre magische Zahl darstellt. Wenn Sie eine Version von Python haben, die keine Enums enthält, können Sie einfach eine Klasse mit einigen statischen Konstanten definieren, um den gleichen Effekt zu erhalten (und eine Methode zum Testen der Krypten zu erstellen, die eine magische Zahl enthält)). Eine solche könnte eine Klasse wie folgt aussehen:

class CryptKeys(object): 
    crypt_masks = { 
        'crypt_unknown':1, 
        .... 
        'crypt_unknown_nonwep': (1 << 18) 
        } 
    @classmethod 
    def find_crypts(cls, magic_number): 
     if magic_number == 0: 
      return ['crypt_none'] 
     else: 
      return [name for name, mask in cls.crypt_masks.items() if magic_number & mask == mask] 
+0

genial, das funktioniert gut – WraithWireless