2011-02-06 76 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