2014-04-27 87 views
5

綜觀packet_ieee80211.h天命的源代碼段轉換Ç枚舉位字段到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), 
}; 

我明白這是移位,但僅此而已。假設我有INT 706,我該如何突破這個數字向上進入cryptset如上即定義我如何可以提取隱窩用來給706尤其是移植到Python

感謝

回答

3

Aruisdante的答案是很不錯的,我只是想對答案擴大,如果你必須使用一個Python之前的3.4,因爲PyPI上有does exist a backport

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

所以,你必須這裏明白的是,這個枚舉定義了一系列bitmasks。在這種情況下,這些枚舉值中的每一個(二進制)都只包含一個1。例如,

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

依此類推。使用位位移運算符是代表「我想第n + 1的二進制位是標記」

這樣我們就可以按位or一堆這些值在一起,並得到一個幻數的只是一個簡單的方法是將這些隱藏值的組合唯一地描述爲位標誌。爲了測試是否幻數包含一個值,我們可以簡單地按位and它與我們希望測試

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

has_wephas_wpatrue當且僅當magic_number包含在這些位標誌的值。

所以讓我們看看數字706,這在二進制是0b1011000010。我們可以看看這個,馬上看,它必須已建成crypt_wepcrypt_wpacrypt_pskcrypt_aes_ccm,因爲正確的位爲這些值設定。

那麼如何移植到python?那麼,python有enums就像C/C++所做的那樣,如果你使用的是python 3.4或更高版本。因此,您可以簡單地在python中創建相同的枚舉表,並應用相同的按位測試來確定您的幻數代表什麼。如果你使用的是沒有枚舉的python版本,你可以簡單地定義一個包含一些靜態常量的類來獲得相同的效果(並且構建一個方法來測試一組幻數中包含的隱變)。這樣的類看起來是這樣的:

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

真棒,很棒的作品 – WraithWireless