1

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')]
4

1 に答える 1

3

IMHO a good point to start is to make converters from dotted string into int and back. Integer representation is more convenient to compare.

I thought about using reduce but it seems too difficult for me. 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.

于 2011-08-02T22:00:03.230 に答える