一个简化CIDR表的脚本

一个简化CIDR表的脚本

最近调整路由器的静态路由,想把收集到的cidr表归集缩短一下,google一番发现只有一个freebsd的ports程序可以实现。没有现成的freebsd,总不能现装吧。用python编了一个,发现挺好用。丢上来分享给CU的朋友。

欢迎debug.
usage:
[python] agg.py filename
or
cmd | [python] agg.py
文件格式
172.16.0.0/16
每行一个cidr地址

用到了defaultdict,所以仅支持2.5。

[Copy to clipboard] [ - ]
CODE:
import sys
from collections import defaultdict
route_map=defaultdict(set)
try:
    input_file=open(sys.argv[1],'r')
except:
    input_file=sys.stdin
iplist=set()
ln=0
for line in input_file:
    ln+=1
    try:
        ip,mask=line.split('/')
        mask=32-int(mask)
        ip=reduce(lambda a,b:(a<<8)+b,[int(i) for i in ip.split('.')])>>mask
    except:
        print >>sys.stderr,'%d invaild data' % ln
        continue
    iplist.add((mask,ip))
for mask,ip in sorted(iplist,reverse=True):
    for i in sorted((k for k in route_map.iterkeys() if k>=mask)):
        ip_set=route_map[i]
        if i==mask:
            if ip in ip_set:
                break
            if ip^1 in ip_set:
                ip_set.remove(ip^1)
                ip=ip/2
                mask+=1
        else:
            if ip>>i-mask in ip_set:
                break
    else:
        route_map[mask].add(ip)
for mask in route_map.iterkeys():
    for ip in route_map[mask]:
        ip=ip<<mask
        first = int((ip >> 24) & 255)
        second = int((ip >> 16) & 255)
        third = int((ip >> 8) & 255)
        fourth = int(ip & 255)
        print '%d.%d.%d.%d/%d' % (first, second, third, fourth,32-mask)

好东西,收藏了。
不错。顶一个。实用小脚本
没用过Python,不过还是顶啊。