2011-02-06 3 views
3

Я работаю над созданием встроенного сетевого устройства (на основе Linux) и столкнулся с необходимостью динамического создания файлов conf-файлов daemon. Таким образом, мне нужно иметь возможность выполнять вычисления сетевых адресов в коде python, который будет создавать файлы conf. Я не программист, поэтому я боюсь, что написал модуль, который не сможет функционировать, как я надеялся, когда устройство начнет поставляться.Python Network/cidr Calculations

Ниже приведено то, что у меня есть до сих пор, оно действительно собрано вместе с тем, что я мог найти на этом сайте и в Google.

Есть ли лучший способ найти сетевой адрес и cidr для сетевого интерфейса? Преобразование сетевой маски в бин-стрит и подсчет 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

+1

Ах! Я полагал, что кто-то, должно быть, уже сделал это, спасибо @sebastian – tMC

ответ

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 
+0

O (log (x)), я думаю; вы зацикливаете число бит в x, а не на x. – DSM

Смежные вопросы