Python 3: создать список возможных IP-адресов из нотации CIDR
Мне была поручена задача создания функции в python (3.1), которая примет нотацию CIDR и вернет список возможных IP-адресов. Я просмотрел python.org и нашел это:
http://docs.python.org/dev/py3k/library/ipaddr.html
но я не видел ничего, что бы заполнило эту потребность... Я был бы очень благодарен за любую помощь, которой кто-либо хочет побить меня. заранее спасибо.: -)
Ответы
Ответ 1
Если вы не состоите в браке с использованием встроенного модуля, существует проект под названием netaddr, который является лучшим модулем я используются для работы с IP-сетями.
Посмотрите IP-учебник, который иллюстрирует, как легко он работает с сетями и определяет их IP-адреса. Простой пример:
>>> 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
Ответ 2
Я предпочел бы сделать небольшую математику, а не устанавливать внешний модуль, с тобой никто не имеет такого же вкуса?
#!/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)
# excludes the first and last address in the subnet
for i in range(start, end):
print(socket.inet_ntoa(struct.pack('>I',i)))
Ответ 3
Вы проверили iptools
? Кажется, это довольно хорошо подходит.
Ответ 4
Это не в документации, но просмотр источника предполагает, что ipaddr
реализует __iter__
и iterhosts
, что именно то, что вы хотите.
Err, неважно.
- Похоже, что
ipaddr.py
был добавлен в stdlib в версии 3.1 beta, но удален с помощью 3.1 rc.
- Я смотрел на источники из оригинального ipaddr.py, который, кажется, эволюционировал отдельно от копии на python.org.
Вы можете просто связать последнюю.
Ответ 5
Ниже код будет генерировать диапазон IP при предоставлении IP и подсети. Разверните обозначение CIDR наподобие (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
Ответ 6
В Python 3 так же просто, как
>>> import ipaddress
>>> [str(ip) for ip in ipaddress.IPv4Network('192.0.2.0/28')]
['192.0.2.0', '192.0.2.1', '192.0.2.2',
'192.0.2.3', '192.0.2.4', '192.0.2.5',
'192.0.2.6', '192.0.2.7', '192.0.2.8',
'192.0.2.9', '192.0.2.10', '192.0.2.11',
'192.0.2.12', '192.0.2.13', '192.0.2.14',
'192.0.2.15']