2011-02-06 77 views
3

我正在構建嵌入式網絡設備(基於Linux),並且遇到了動態構建守護程序conf文件的需求。因此,我需要能夠在構建conf文件的python代碼中執行一些網絡地址計算。我不是一名程序員,所以我很害怕我寫了一個模塊,當我的設備開始出貨時,它將無法正常工作。Python網絡/ cidr計算

下面是我到目前爲止,它真的拼湊在一起,我可以在這個網站上找到和谷歌。

是否有更好的方法來查找網絡接口的網絡地址和cidr?將網絡掩碼轉換爲bin str並計算1,似乎很不雅觀。

import socket 
import fcntl 
import struct 

SIOCGIFNETMASK = 0x891b 
SIOCGIFADDR = 0x8915 

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 

def _GetIfaceMask(iface): 
    return struct.unpack('L', fcntl.ioctl(s, SIOCGIFNETMASK, struct.pack('256s', iface))[20:24])[0] 

def _GetIfaceAddr(iface): 
    return struct.unpack('L', fcntl.ioctl(s, SIOCGIFADDR, struct.pack('256s', iface[:15]))[20:24])[0] 

def GetIfaceNet(iface): 
    net_addr = _GetIfaceAddr(iface) & _GetIfaceMask(iface) 
    return socket.inet_ntoa(struct.pack('L', net_addr)) 

def GetIfaceCidr(iface): 
    bin_str = bin(_GetIfaceMask(iface))[2:] 
    cidr = 0 
    for c in bin_str: 
     if c == '1': cidr += 1 
    return cidr 

感謝您的任何意見,我真的有點失落。如果這不是這種類型的反饋的地方,請讓我知道。

+1

你試過`netaddr`或`ipaddr`模塊? – jfs 2011-02-06 15:28:47

+1

啊!我想有人肯定已經這樣做了 - 謝謝@sebastian – tMC 2011-02-06 17:50:53

回答

4

這可以使用海明加權算法來解決。從How to count the number of set bits in a 32-bit integer?被盜翻譯成Python:

def number_of_set_bits(x): 
    x -= (x >> 1) & 0x55555555 
    x = ((x >> 2) & 0x33333333) + (x & 0x33333333) 
    x = ((x >> 4) + x) & 0x0f0f0f0f 
    x += x >> 8 
    x += x >> 16 
    return x & 0x0000003f 

另外,可讀性更強的解決方案(但運行在O(log x)):

def number_of_set_bits(x): 
    n = 0 
    while x: 
     n += x & 1 
     x = x >> 1 
    return n