2009-12-21 45 views
10

Me han encomendado la tarea de crear una función en python (3.1) que tomará una notación CIDR y devolverá la lista de posibles direcciones IP. Miré a través de python.org y encontré esto: http://docs.python.org/dev/py3k/library/ipaddr.htmlPython 3: crear una lista de direcciones IP posibles a partir de una notación CIDR

pero no he visto nada que llene esta necesidad ... Estaría muy agradecido por cualquier ayuda que a alguien le importe patearme. gracias por adelantado. :-)

+4

posible que desee volver atrás y aceptar algunas respuestas a sus preguntas si fueran útiles ... –

+0

he utilizado del API (http://c0re.23.nu/c0de/IPy/) en Python 2. x, y ahora estoy en el proceso de portarlo a Python 3. Voy a publicar un enlace como respuesta una vez que haya terminado. –

+0

@AJ: IPy también es una buena opción, pero recomendé netaddr porque me gusta más. :) – jathanism

Respuesta

1

¿Has comprobado iptools? Parece ser un ajuste bastante bueno.

+0

Dado que parece que no es compatible con Python 2.3, probablemente requerirá al menos una cantidad nominal de esfuerzo para admitir Python 3.1. – ephemient

+2

He actualizado iptools para admitir Python 2.3, 2.5, 2.6 y 3.1. – bd808

0

No aparece en la documentación, pero al examinar la fuente se sugiere que ipaddr implementa __iter__ y iterhosts, que es exactamente lo que desea.


Err, nevermind.

  1. Parece que ipaddr.py se añadió a stdlib en 3.1 beta, pero se eliminó por 3.1 rc.
  2. Estaba viendo las fuentes del original ipaddr.py, que parece haber evolucionado por separado de la copia en python.org.

Puede agrupar este último.

24

Si no está casado con el uso del módulo integrado, hay un proyecto llamado netaddr que es el mejor módulo que he usado para trabajar con redes IP.

Eche un vistazo a IP Tutorial que ilustra lo fácil que es trabajar con redes y discernir sus direcciones IP. Ejemplo simple:

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

El siguiente código generará un rango de direcciones IP para proporcionar IP y subred. Ampliar la notación CIDR como (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

yo preferiría hacer un poco de matemáticas en lugar de instalar un módulo externo, nadie tiene el mismo gusto conmigo?

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

Tenga en cuenta que esto excluye la dirección de difusión, que puede ser o no lo que desea. Quite el '-1' al calcular" end "para incluirlo. – Peter

Cuestiones relacionadas