【发布时间】:2013-07-15 20:50:42
【问题描述】:
我正在尝试转换一组可以在任何给定地址上开始和结束的 IP 范围,但不一定在 .0、.127 或 .255 等上。我的代码大部分都在工作;但是,对于大范围,它可能会很慢。
例如find_range("1.40.0.0","1.44.255.255") 将需要一分钟以上才能返回1.40.0.0/14 和1.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...
【问题讨论】:
-
您是否尝试过查看 ipaddress.py 中的现有代码? code.google.com/p/ipaddress-py/source/browse/ipaddress.py#248
-
@bsdlp:这看起来像我需要的。谢谢!
标签: python networking ip-address