Python 3: создать список возможных IP-адресов из нотации CIDR - PullRequest
10 голосов
/ 21 декабря 2009

Мне передали задачу создания функции в python (3.1), которая будет принимать нотацию CIDR и возвращать список возможных IP-адресов. Я посмотрел вокруг python.org и нашел это: http://docs.python.org/dev/py3k/library/ipaddr.html

но я не видел ничего, что могло бы удовлетворить эту потребность ... Я был бы очень признателен за любую помощь, если кто-нибудь захочет пнуть меня. заранее спасибо. : -)

Ответы [ 7 ]

34 голосов
/ 22 декабря 2009

Если вы не женаты на использовании встроенного модуля, существует проект под названием netaddr , который является лучшим модулем, который я использовал для работы с IP-сетями.

Взгляните на IP Tutorial , который показывает, как легко работать с сетями и распознавать их 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
9 голосов
/ 18 мая 2017

Я бы предпочел сделать небольшую математику, а не устанавливать внешний модуль, никто не имеет такой же вкус со мной?

#!/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)))
7 голосов
/ 06 декабря 2018

В 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']
1 голос
/ 21 декабря 2009

Вы проверили iptools? Вроде бы неплохо подойдет.

0 голосов
/ 02 марта 2019

Генерация всех общедоступных IP-адресов с учетом CIDR

https://github.com/stephenlb/geo-ip создаст список допустимых публичных IP-адресов, включая населенные пункты.

'1.0.0.0/8' - '191.0.0.0/8' - действительный диапазон общедоступных IP-адресов, исключая зарезервированные частные IP-адреса.

IP-генератор

Создает дамп JSON IP-адресов и связанной гео-информации. Обратите внимание, что действительный публичный диапазон IP-адресов от '1.0.0.0/8' до '191.0.0.0/8' исключая зарезервированные Частные диапазоны IP-адресов показаны ниже в этом файле readme.

docker build -t geo-ip .
docker run -e IPRANGE='54.0.0.0/30' geo-ip               ## a few IPs
docker run -e IPRANGE='54.0.0.0/26' geo-ip               ## a few more IPs
docker run -e IPRANGE='54.0.0.0/16' geo-ip               ## a lot more IPs
docker run -e IPRANGE='0.0.0.0/0'   geo-ip               ## ALL IPs ( slooooowwwwww )
docker run -e IPRANGE='0.0.0.0/0'   geo-ip > geo-ip.json ## ALL IPs saved to JSON File
docker run geo-ip 

Немного более быстрый вариант для сканирования всех действительных публичных адресов:

for i in $(seq 1 191); do \
    docker run -e IPRANGE="$i.0.0.0/8" geo-ip; \
    sleep 1; \ 
done

Это печатает меньше чем 4,228,250,625 строк JSON в STDOUT. Вот пример одной из строк:

{"city": "Palo Alto", "ip": "0.0.0.0", "longitude": -122.1274,
 "continent": "North America", "continent_code": "NA",
 "state": "California", "country": "United States", "latitude": 37.418,
 "iso_code": "US", "state_code": "CA", "aso": "PubNub",
 "asn": "11404", "zip_code": "94107"}

Частный и зарезервированный диапазон IP-адресов

Dockerfile в репозитории выше исключит неиспользуемые IP-адреса следуя руководству из статьи википедии: https://en.wikipedia.org/wiki/Reserved_IP_addresses

MaxMind Geo IP

Dockerfile импортирует бесплатную общедоступную базу данных, предоставленную https://www.maxmind.com/en/home

0 голосов
/ 23 сентября 2016

Код ниже будет генерировать диапазон 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 
0 голосов
/ 21 декабря 2009

Этого нет в документации, но просмотр источника предполагает, что ipaddr реализует __iter__ и iterhosts, что именно то, что вы хотите.


Ошибка, неважно.

  1. Похоже, ipaddr.py был добавлен в stdlib в бета-версии 3.1, но удален на 3.1 rc.
  2. Я искал источники из оригинального ipaddr.py , который, похоже, развивался отдельно от копии на python.org.

Вы можете просто связать последнее.

...