简体   繁体   English

Python-将IP地址列表转换为地址范围列表

[英]Python - convert list of IP addresses to a list of address ranges

There are multiple ways to convert a list of IP address to a list of CIDR (netaddr, ipaddr-py). 有多种方法可以将IP地址列表转换为CIDR列表(netaddr,ipaddr-py)。 Is there a way to convert a list of IP address ranges to a merged IP range? 有没有办法将IP地址范围列表转换为合并的IP范围?

Note this is a more general question of my previous question on glob formatting . 请注意,这是我先前关于glob格式设置问题的一个更一般的问题。

The following examples return a list of tuples of the following format: [(start, end)] . 下面的示例返回以下格式的元组列表: [(start, end)]

Example 1: 例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')]

Example 2: 例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')]

IMHO a good point to start is to make converters from dotted string into int and back. 恕我直言,一个很好的起点是使转换器从点串转换为int并返回。 Integer representation is more convenient to compare. 整数表示法比较起来比较方便。

I thought about using reduce but it seems too difficult for me. 我考虑过使用reduce,但是对我来说似乎太困难了。 So I've just implemented it using traditional loop and without recursion. 因此,我只是使用传统循环实现了它,没有递归。

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

EDIT : bug fixed. 编辑 :修正了错误。

Also I've made an alternative solution: 我也提出了一个替代解决方案:

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 )

Let me give you some advice for the future. 让我给你一些关于未来的建议。 Do not ask people to write code for you. 不要要求别人为您编写代码。 I helped you just because I was interested to make the code as small as I can and improve my own knowledges. 我之所以向您提供帮助,是因为我有兴趣使代码尽可能的小,并提高自己的知识。 But Robin Hood is not always here. 但是罗宾汉并不总是在这里。 Try to develop something yourself and we will help you to find your mistakes in algorithms and code. 尝试自己开发一些东西,我们将帮助您发现算法和代码中的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM