2009-12-21 17 views
10

Zostałem przekazany zadanie utworzenia funkcji w python (3.1), która zajmie notację CIDR i zwróci listę możliwych adresów IP. Rozejrzałem się po python.org i znalazłem to: http://docs.python.org/dev/py3k/library/ipaddr.htmlPython 3: utwórz listę możliwych adresów IP z notacji CIDR

ale nie widziałem niczego, co wypełniłoby tę potrzebę ... Byłbym bardzo wdzięczny za jakąkolwiek pomoc, którą każdy kogo kopie po swojemu. z góry dziękuję. :-)

+4

chcieć wrócić i przyjąć kilka odpowiedzi na pytania, czy byli pomocni ... –

+0

Użyłem IPY (http://c0re.23.nu/c0de/IPy/) na Pythonie 2. x, a teraz jestem w trakcie przenoszenia go do Pythona 3. Kiedy już skończę, opublikuję link jako odpowiedź. –

+0

@AJ: IPy to także dobry wybór, ale poleciłem netaddr, ponieważ podoba mi się to lepiej. :) – jathanism

Odpowiedz

1

Czy wymeldowałeś się iptools? Wygląda na dość dobre dopasowanie.

+0

Biorąc pod uwagę, że wydaje się nie obsługiwać Python 2.3, prawdopodobnie wymagałoby to co najmniej nominalnego wysiłku, aby wesprzeć Python 3.1. – ephemient

+2

Zaktualizowałem program iptools, aby obsługiwał Python 2.3, 2.5, 2.6 i 3.1. – bd808

0

To nie jest w dokumentacji, ale przeglądając źródła sugerują, że ipaddr realizuje __iter__ i iterhosts, który jest dokładnie to, co chcesz.


Err, nevermind.

  1. Wygląda na to, że ipaddr.py został dodany do stdlib w wersji 3.1 beta, ale usunięty przez 3.1 rc.
  2. Szukałem źródeł z oryginalnego ipaddr.py, który wydaje się ewoluował niezależnie od kopii na python.org.

Możesz po prostu spakować to ostatnie.

24

Jeśli nie jesteś żonaty, używając wbudowanego modułu, istnieje projekt o nazwie netaddr, który jest najlepszym modułem, którego użyłem do pracy z sieciami IP.

Zapoznaj się z numerem IP Tutorial, który pokazuje, jak łatwa jest praca z sieciami i rozpoznawanie ich adresów IP. Prosty przykład:

>>> from netaddr import IPNetwork 
>>> for ip in IPNetwork('192.0.2.0/23'): 
... print '%s' % ip 
... 
192.0.2.0 
192.0.2.1 
192.0.2.2 
192.0.2.3 
... 
192.0.3.252 
192.0.3.253 
192.0.3.254 
192.0.3.255 
0

Poniższy kod wygeneruje zakres adresów IP dla IP i podsieci. Rozwiń notacji CIDR jak (255.255.255.0)

from netaddr import * 

def getFirstIp(ipAddress,subnet): 
    ipBin = IPNetwork(ipAddress).ip.bits().split('.') 
    subBin = IPNetwork(subnet).ip.bits().split('.') 
    zipped = zip(ipBin,subBin) 
    netIdList = [] 
    for octets in zipped: 
    netIdList.append(''.join(str(b) for b in (map((lambda x: int(x[0])*int(x[1])),zip(list(octets[0]),list(octets[1])))))) 
    firstIp = '' 
    firstIp = '.'.join(str(int(oct,2)) for oct in netIdList) 
    return firstIp 


def getLastIp(ipAddress,subnet): 
    ipBin = IPNetwork(ipAddress).ip.bits().split('.') 
    subBin = IPNetwork(subnet).ip.bits().split('.') 
    #print ipBin 
    #print subBin 
    revsubBin = [] 
    for octets in subBin: 
    revB = ''.join('1' if(b == '0') else '0' for b in octets) 
    revsubBin.append(revB) 
    zipped = zip(ipBin,revsubBin) 
    netIdList = [] 
    for octets in zipped: 
    netIdList.append(''.join(str(b) for b in (map((lambda x: 0 if(int(x[0]) == 0 and int(x[1]) == 0) else 1),zip(list(octets[0]),list(octets[1])))))) 
    #print netIdList 
    lastIp = '' 
    lastIp = '.'.join(str(int(oct,2)) for oct in netIdList) 
    return lastIp 

def getRangeOfIps(firstIp,lastIp): 
    start= int(IPAddress(firstIp)) 
    end = int(IPAddress(lastIp)) 
    ipList = [] 
    for ip in range(start,end+1): 
    ipList.append(str(IPAddress(ip))) 
    return ipList 

def manipulateIP(): 
firstIp = getFirstIp(ipAddress,subnet) 
lastIp = getLastIp(ipAddress,subnet) 
ipList = getRangeOfIps(firstIp,lastIp) 
print ipList 
3

wolałbym robić trochę matematyki zamiast instalowania modułu zewnętrznego, nikt nie ma ten sam smak ze mną?

#!/usr/bin/env python 
# python cidr.py 192.168.1.1/24 

import sys, struct, socket 

(ip, cidr) = sys.argv[1].split('/') 
cidr = int(cidr) 
host_bits = 32 - cidr 
i = struct.unpack('>I', socket.inet_aton(ip))[0] # note the endianness 
start = (i >> host_bits) << host_bits # clear the host bits 
end = start | ((1 << host_bits) - 1) 

for i in range(start, end): 
    print(socket.inet_ntoa(struct.pack('>I',i))) 
+0

Należy pamiętać, że wyklucza to adres broadcast, który może być lub nie jest tym, co chcesz. Usuń "-1" podczas obliczania "końca", aby je uwzględnić. – Peter