распространение диапазона IP-адресов в список - PullRequest
2 голосов
/ 02 июня 2019

У меня есть следующий код, который я пытаюсь сделать, это создать небольшую функцию, чтобы при вводе диапазона IP-адресов (содержит: в нем) весь диапазон добавлялся в список.

collected_ips = []
while True:
    query = input("IP:\t")
    if not query:
        break
    elif len(query.split('.'))==4:
        temp = query.split('.')
        #result1 = all([i.isdigit() for i in t]) #must be True
        if query.find(":")==-1:
            try:
                result2 = all([0<=int(i)<=255 for i in temp])
                if result2:
                    collected_ips.append(query)
            except ValueError:
                print("Please Fix Input")
        elif len(x.split(":"))==2:
            #function here
            #append to collected_ips
        else:
            print("Please Fix Input")
    else:
        print("Please Fix Input")

пример ввода:

123.123.30.20:50

вывод:

['123.123.30.20,'123.123.30.21'...'123.123.30.50']

пример ввода:

123.123.20:50.30

выход:

['123.123.20.30','123.123.21.30',...'123.123.50.30']

Ответы [ 2 ]

1 голос
/ 02 июня 2019

Вы также можете сделать это более кратко, используя Reduce (из functools):

from functools import reduce
def expandIp(ip):
  nodes  = [list(map(int,n.split(":"))) for n in ip.split(".")]
  ranges = [range(max(n[0],0),min(n[-1]+1,256)) for n in nodes]
  ips    = reduce(lambda a,rng: [ip+[n] for ip in a for n in rng],ranges,[[]])
  return [".".join(str(n) for n in ip) for ip in ips]
  • nodes преобразует шаблон ip в список значений диапазона [start] или [start, end]
  • ranges преобразует узлы в фактические диапазоны, используя начальный номер в качестве конца, когда для узла нет спецификатора ':' (также ограничивает узел диапазоном 0 ... 255)
  • ips объединяет каждый диапазон узлов со всеми значениями предыдущих узлов
  • Результатом является объединение узлов в каждой комбинации с "." в качестве разделителя

примечание: это решение будет работать для нескольких спецификаторов диапазона в параметре ip. например expandIp("10.1.1:2.100:101") будет производить: 10.1.1.100, 10.1.1.101, 10.1.2.100, 10.1.2.101. Так что если вы собираетесь использовать его для подсетей, вы сможете сделать expandIp("10.0.1:3.0:255")

Кстати, вы можете проверить параметр ip с помощью одного условия в начале функции или перед ее вызовом (тогда вам не нужно будет использовать min / max для присвоения переменной ranges):

n0255 = { str(n) for n in range(256) }  
if not all( i<4 and j<2 and r in n0255 for i,n in enumerate(ip.split(".")) for j,r in enumerate(n.split(":"))):
    print("Invalid Input")

Последняя функция будет выглядеть так:

from functools import reduce
n0255 = { str(n) for n in range(256) }  
def expandIp(ip):
  if not all( i<4 and j<2 and r in n0255 for i,n in enumerate(ip.split(".")) for j,r in enumerate(n.split(":"))):
      return None
  nodes  = [list(map(int,n.split(":"))) for n in ip.split(".")]
  ranges = [range(n[0],n[-1]+1) for n in nodes]
  ips    = reduce(lambda a,rng: [ip+[n] for ip in a for n in rng],ranges,[[]])
  return [".".join(str(n) for n in ip) for ip in ips]

, что упростит ваш код вызова до:

collected_ips = []
while True:
    query = input("IP:\t")
    if not query:
        break
    ips = expandIp(query)
    if not ips:
        print("Invalid Input")
    else:
        collected_ips += ips
1 голос
/ 02 июня 2019

Это один подход, использующий range для генерации чисел между двумя диапазонами:

def spread_ip_range(ip):
    splits = ip.split('.')
    indx = next((i for i, x in enumerate(splits) if ':' in x), -1)

    lst = []

    if indx != -1:
        _from, to = splits[indx].split(':')
        ranges = range(max(0, int(_from)), min(255, int(to)) + 1))

        for r in ranges:
            s = '.'.join(splits[:indx]) + '.' + str(r)
            if splits[indx+1:]:
                s += '.' + '.'.join(splits[indx+1:])
            lst.append(s)
    return lst

Использование :

>>> spread_ip_range('123.123.20:50.30')
['123.123.20.30', '123.123.21.30', '123.123.22.30', ......, '123.123.49.30', '123.123.50.30']

-

>>> spread_ip_range('123.123.30.20:50')
['123.123.30.20', '123.123.30.21', '123.123.30.22', ......, '123.123.30.49', '123.123.30.50']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...