2013-07-15 94 views
0

我想转换一组IP范围,可以开始和结束任何给定的地址,但不一定在.0,.127或.255等我有代码主要是工作;但是,对于大范围它可能会很慢。在Python中的IP地址网络3.3

例如find_range("1.40.0.0","1.44.255.255")将花费一分钟以返回1.40.0.0/141.44.0.0/16的正确结果。

此外,当起始范围不以.0结尾时,我遇到了麻烦。我该如何解决这两个问题:大IP范围的缓慢时间和起始范围不以.0结尾?

对于缓慢的问题,我试过一次跳过1个以上的地址,但是这样会错过更小的范围。

import ipaddress, socket, struct 

def ip2int(addr):                
    return struct.unpack("!I", socket.inet_aton(addr))[0]      

def int2ip(addr):                
    return socket.inet_ntoa(struct.pack("!I", addr))   

def ipminus(ip, amount=1): 
    tmp = ip2int(ip) 
    return int2ip(tmp - amount) 

def ipplus(ip): 
    tmp = ip2int(ip) 
    return int2ip(tmp + 1) 

def cidr_notation(a,b): 
    for mask in range(32, 6, -1): 
     test = "%s/%s" % (a,mask) 
     try: 
      n = ipaddress.IPv4Network(test,False) 
      if b == "%s" % (n.broadcast_address): 
       return test 
     except: 
      pass 
    return None 

def split_range(a,b): 
    a1 = ip2int(a) 
    b1 = ip2int(b) 

    needed = 1 
    while needed: 
     result = cidr_notation(a,b) 
     if result: 
      print("* %16s\t%16s\t%16s" % (result, a, b)) 
      if ip2int(b) > b1: 
       needed = 0 
      else: 
       a = ipplus(b) 
       b = int2ip(b1) 
     else: 
      b = ipminus(b) 

    return result 

def find_range(x,y): 
    result = cidr_notation(x,y) 
    if result: 
     print("# %16s\t%16s\t%16s" % (result, x, y)) 
    else: 
     split_range(x,y) 

# main... 
print("%16s\t%16s\t%16s" % ("mask","start","end")) 
print("%16s\t%16s\t%16s" % ("----","-----","---")) 

find_range("128.191.0.0","128.191.255.255") #fast 
find_range("10.55.96.106","10.55.96.106") #fast 
find_range("5.135.14.0","5.135.61.11") #slow 
find_range("4.31.64.72","4.59.175.255") #does not work, how to fix? 
find_range("1.40.0.0","1.44.255.255") #very slow 
# 5000 more find_range() calls... 
+1

您是否试过从ipaddress.py中查看此现有代码? https://code.google.com/p/ipaddress-py/source/browse/ipaddress.py#248 –

+0

@bsdlp:这看起来像我需要的。谢谢! – jftuga

回答

1

基于bsdlp的评论,这段代码变得更简单快捷了!

def find_range(x,y,c_code="",c_name=""): 
    print() 
    print("%29s\t%23s" % (x,y)) 
    print("%16s\t%16s\t%16s\t%4s\t%s" % ("mask","start","end","code","name")) 
    print("%16s\t%16s\t%16s\t%4s\t%s" % ("----","-----","---","----","----")) 

    result = ipaddress.summarize_address_range(ipaddress.IPv4Address(x), ipaddress.IPv4Address(y)) 
    for entry in result: 
     net = str(entry.network_address) 
     bcast = str(entry.broadcast_address) 
     print("%16s\t%16s\t%16s\t%4s\t%s" % (entry, net, bcast,c_code,c_name))