2009-12-21 14 views
10

Mi è stato assegnato il compito di creare una funzione in python (3.1) che prenderà una notazione CIDR e restituirà l'elenco di possibili indirizzi ip. Ho dato un'occhiata a python.org e ho trovato questo: http://docs.python.org/dev/py3k/library/ipaddr.htmlPython 3: crea un elenco di possibili indirizzi IP da una notazione CIDR

ma non ho visto nulla che soddisfi questo bisogno ... Sarei molto grato per qualsiasi tipo di assistenza che qualcuno abbia a prendermi a calci. Grazie in anticipo. :-)

+4

potrebbe desiderare di tornare indietro e accettare alcune risposte alle tue domande se fossero utili ... –

+0

Ho usato IPY (http://c0re.23.nu/c0de/IPy/) su Python 2. x, e ora sono in procinto di portarlo su Python 3. Pubblicherò un link come risposta una volta che ho finito. –

+0

@AJ: IPy è anche una buona scelta, ma ho raccomandato netaddr perché mi piace di più. :) Aggiornamento – jathanism

risposta

1

Avete controllato iptools? Sembra essere abbastanza in forma.

+0

Dato che sembra non supportare Python 2.3, probabilmente richiederebbe almeno una quantità nominale di sforzo per supportare Python 3.1. – ephemient

+2

Ho aggiornato iptools per supportare Python 2.3, 2.5, 2.6 e 3.1. – bd808

0

Non è nella documentazione, ma la navigazione nella fonte suggerisce che ipaddr implementa __iter__ e iterhosts, che è esattamente ciò che si desidera.


Err, non importa.

  1. Sembra che ipaddr.py sia stato aggiunto a stdlib in 3.1 beta, ma rimosso da 3.1 rc.
  2. Stavo osservando le origini dell'originale ipaddr.py, che sembra essersi evoluta separatamente dalla copia su python.org.

Si potrebbe semplicemente impacchettare quest'ultimo.

24

Se non si è sposati con il modulo integrato, esiste un progetto chiamato netaddr che è il modulo migliore che ho utilizzato per lavorare con le reti IP.

Dai uno sguardo allo IP Tutorial che illustra quanto sia facile lavorare con le reti e discernere i loro IP. Esempio semplice:

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

Il codice sottostante genererà un intervallo di IP su IP e subnet. Espandere la notazione CIDR come (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

io preferirei fare un po 'di matematica, piuttosto che l'installazione di un modulo esterno, nessuno ha lo stesso gusto con me?

#!/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

Si noti che questo esclude l'indirizzo di trasmissione, che può o non può essere quello che vuoi. Rimuovere il '-1' quando si calcola" end "per includerlo. – Peter

Problemi correlati