Python—计算IP范围内IP的最佳方法
我有一个python脚本,它从arp表中获取所有IP并将其分配给一个变量。我有一个for循环,它创建了另外两个变量start_IP(包含子网的第一个IP)和last_IP(包含同一子网的最后一个IP)。对于每个循环,我将有一个不同的开始和最后的IP 我试图检查包含所有IP的变量,看看每个子网下有多少IP 最好的方法是什么?下面是一个硬编码示例: 计数=0Python—计算IP范围内IP的最佳方法,python,python-2.7,ip,Python,Python 2.7,Ip,我有一个python脚本,它从arp表中获取所有IP并将其分配给一个变量。我有一个for循环,它创建了另外两个变量start_IP(包含子网的第一个IP)和last_IP(包含同一子网的最后一个IP)。对于每个循环,我将有一个不同的开始和最后的IP 我试图检查包含所有IP的变量,看看每个子网下有多少IP 最好的方法是什么?下面是一个硬编码示例: 计数=0 arps = ['10.20.30.130','10.20.30.131','10.20.30.132', '10.20.30.133',
arps = ['10.20.30.130','10.20.30.131','10.20.30.132', '10.20.30.133',
'10.20.30.136', '10.20.30.137', '10.20.30.138', '10.20.30.139', '10.20.30.140', '10.20.30.141', '10.20.30.143', '10.20.30.149']
start_ip = "10.20.30.132"
end_ip = "10.20.30.142"
count = 0
for arp in arps:
if arp >= start_ip and arp <= end_ip:
count = count + 1
print count
else:
continue
print "Count: ", count
arps=['10.20.30.130'、'10.20.30.131'、'10.20.30.132'、'10.20.30.133',
'10.20.30.136', '10.20.30.137', '10.20.30.138', '10.20.30.139', '10.20.30.140', '10.20.30.141', '10.20.30.143', '10.20.30.149']
开始\u ip=“10.20.30.132”
end_ip=“10.20.30.142”
计数=0
对于arp中的arp:
如果arp>=启动ip和arp两种方式。简单的方法是:
IP地址逐八位字节进行比较。有趣的是,Python列出了逐个元素的比较。因此,如果您只需按点拆分IP地址并将列表映射到int
,就可以正确地比较它们
更简单的方法是:
ipaddress.ip\u地址
是可比较的,只要比较的地址是相同的版本(IPv4或IPv6)
但是,字符串比较不能提供IP地址的正确顺序:
'1.12.1.1' < '1.2.1.1'
# => True (should be False)
我可以想到以下两种解决方案。方法1的时间复杂度为O(N)
,方法2的时间复杂度为O(nlogn)
。正如Amadan所建议的,IP地址需要事先进行预处理
import bisect
arps = ['10.20.30.130','10.20.30.131','10.20.30.132', '10.20.30.133',
'10.20.30.136', '10.20.30.137', '10.20.30.138', '10.20.30.139', '10.20.30.140', '10.20.30.141', '10.20.30.143', '10.20.30.149']
start_ip = "10.20.30.132"
end_ip = "10.20.30.142"
# Padding zeros to the IP addresses to make sure they are directly comparable
def padding(s):
return s.zfill(3)
arps = [".".join(list(map(padding, x.split(".")))) for x in arps]
start_ip = ".".join(list(map(padding, start_ip.split("."))))
end_ip = ".".join(list(map(padding, end_ip.split("."))))
# Method 1: Pythonic one-liner
print(sum(start_ip <= x <= end_ip for x in arps))
# Method 2: Sort and binary search
def find_lt(a, x):
i = bisect.bisect_right(a, x)
if i:
return i - 1
else:
return 0
def find_gt(a, x):
i = bisect.bisect_right(a, x)
if i != len(a):
return i
else:
return i
arps.sort()
print(find_gt(arps, end_ip) - find_lt(arps, start_ip))
导入对分
arps=['10.20.30.130'、'10.20.30.131'、'10.20.30.132'、'10.20.30.133',
'10.20.30.136', '10.20.30.137', '10.20.30.138', '10.20.30.139', '10.20.30.140', '10.20.30.141', '10.20.30.143', '10.20.30.149']
开始\u ip=“10.20.30.132”
end_ip=“10.20.30.142”
#将零填充到IP地址以确保它们直接可比
def填充:
返回s.zfill(3)
arps=[“.”.join(在arps中x的列表(映射(填充,x.split(“.”)))
start_ip=“.”join(列表(映射(填充,start_ip.split(“.”)))
end_ip=“.”连接(列表(映射(填充,end_ip.split(“.”)))
#方法1:肾盂一衬
print(sum)(start_ip)这是不正确的,因为我在回答中解释了一个问题-sort
不会按正确的顺序对字符串ip进行排序。@Amadan是的,你是对的。让我来说明一个解决方法。另外,如果忽略排序的事实,方法2的复杂性为O(logn)。排序本身就是O(logn)。(当然,big-O不是速度的度量,只是复杂性…@Amadan-True。谢谢。现在呢?它会起作用的,尽管我认为list(map(int,x.split(“.”))
比”简单得多,也快得多。join(list(map(padding,x.split(“.”)))
。我的数据库中确实有CIDR,因此您的上一个解决方案可能会工作得很好,并尽量减少代码。我会尝试一下!谢谢。我将使用第一个解决方案。我使用的是python 2,因此我必须先将所有IP字符串转换为Unicode才能使其工作。
ipaddress.ip_address('192.168.1.17') in ipaddress.ip_network('192.168.0.0/16')
# => True
import bisect
arps = ['10.20.30.130','10.20.30.131','10.20.30.132', '10.20.30.133',
'10.20.30.136', '10.20.30.137', '10.20.30.138', '10.20.30.139', '10.20.30.140', '10.20.30.141', '10.20.30.143', '10.20.30.149']
start_ip = "10.20.30.132"
end_ip = "10.20.30.142"
# Padding zeros to the IP addresses to make sure they are directly comparable
def padding(s):
return s.zfill(3)
arps = [".".join(list(map(padding, x.split(".")))) for x in arps]
start_ip = ".".join(list(map(padding, start_ip.split("."))))
end_ip = ".".join(list(map(padding, end_ip.split("."))))
# Method 1: Pythonic one-liner
print(sum(start_ip <= x <= end_ip for x in arps))
# Method 2: Sort and binary search
def find_lt(a, x):
i = bisect.bisect_right(a, x)
if i:
return i - 1
else:
return 0
def find_gt(a, x):
i = bisect.bisect_right(a, x)
if i != len(a):
return i
else:
return i
arps.sort()
print(find_gt(arps, end_ip) - find_lt(arps, start_ip))