2013-07-15 142 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))