Python - преобразовать список IP-адресов в список диапазонов адресов - PullRequest
1 голос
/ 03 августа 2011

Существует несколько способов преобразования списка IP-адресов в список CIDR (netaddr, ipaddr-py). Можно ли преобразовать список диапазонов IP-адресов в объединенный диапазон IP-адресов?

Обратите внимание, что это более общий вопрос моего предыдущего вопроса о форматировании глобуса .

Следующие примеры возвращают список кортежей следующего формата: [(start, end)].

Пример 1:

>>> list_of_ips = ['192.168.0.1', '192.168.0.2', '192.168.0.3']
>>> print merge_ip_list(list_of_ips)
[('192.168.0.1','192.168.0.3')]

Пример 2:

>>> list_of_ips2 = ['10.0.0.0', '10.0.0.3', '10.0.0.4']
>>> print merge_ip_list(list_of_ips2)
[('10.0.0.0','10.0.0.0'), ('10.0.0.3','10.0.0.4')]

1 Ответ

3 голосов
/ 03 августа 2011

ИМХО, хороший момент для начала - сделать преобразователи из пунктирной строки в int и обратно. Целочисленное представление удобнее сравнивать.

Я подумал об использовании Reduce, но мне это кажется слишком сложным. Так что я только что реализовал это, используя традиционный цикл и без рекурсии.

def int2dot( intip ):
    return '.'.join([ str( (intip>>x*8) & 0xFF ) for x in [3,2,1,0]])
def dot2int( dotip ):
    return reduce( lambda r,x: int(x)+(r<<8), dotip.split('.'), 0 )

def merge_ip_list(ip_list):
    if not ip_list:
        return []
    orig = map(dot2int,ip_list)
    orig.sort()
    start = orig[0]
    prev = start-1
    res = []
    for x in orig:
        if x != prev+1:
            res.append((int2dot(start),int2dot(prev)))
            start = x
        prev = x
    res.append((int2dot(start),int2dot(prev)))
    return res

РЕДАКТИРОВАТЬ : исправлена ​​ошибка.

Также я сделал альтернативное решение:

def merge_ip_list_alt(ip_list):
    if not ip_list:
        return []
    orig = sorted(map(dot2int,ip_list))
    end, start = zip(*[x for x in zip(orig,orig[1:]) if x[0]+1!=x[1]]) or ((),())
    start = [int2dot(orig[0])] + map(int2dot,start)
    end = map(int2dot,end) + [int2dot(orig[-1])]
    return zip( start, end )

Позвольте дать вам совет на будущее. Не просите людей писать код для вас. Я помог вам только потому, что мне было интересно сделать код как можно меньше и улучшить свои знания. Но Робин Гуд не всегда здесь. Попробуйте сами разработать что-нибудь, и мы поможем вам найти ошибки в алгоритмах и коде.

...