我有一个python脚本,可从arp表中获取所有IP,并将其分配给变量。我有一个for循环,它创建另外两个变量start_IP,它们包含一个子网的第一个IP,而last_IP包含相同子网中的最后一个IP。对于每个循环,我将有不同的开始和结束IP。
我正在尝试检查包含所有IP的变量,并查看每个子网下有多少IP。
什么是最好的方法?这是一个硬编码的示例: 计数= 0
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, Click Me!</string>
<string name="app_name">SpinnerArray</string>
<string name="on_off">On or Off</string>
<string-array name="spinnerArray">
<item>On</item>
<item>Off</item>
</string-array>
</resources>
是否有更好的更快的方法?
答案 0 :(得分:3)
两种方式。简单的方法:
IP地址逐字节比较八位字节。有趣的是,Python列表按元素进行比较。因此,如果仅将IP地址按点分隔并将列表映射到int
,则可以正确比较它们。
更简单的方法:
ipaddress.ip_address
是可比较的,只要比较的地址是同一版本(IPv4或IPv6)即可。
但是,字符串比较不能提供正确的IP地址排序:
'1.12.1.1' < '1.2.1.1'
# => True (should be False)
除这些问题外,您的代码都可以。它可以写得更简洁:
import ipaddress
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"
start_ip_ip = ipaddress.ip_address(start_ip)
end_ip_ip = ipaddress.ip_address(end_ip)
sum(1 for ip in arps if start_ip_ip <= ipaddress.ip_address(ip) <= end_ip_ip)
# => 8
如果您特别想查看特定子网中的地址,那么即使您知道子网规格,甚至不需要使用起始地址和结束地址:
ipaddress.ip_address('192.168.1.17') in ipaddress.ip_network('192.168.0.0/16')
# => True
答案 1 :(得分:2)
我可以想到以下两种解决方案。方法1的时间复杂度为O(N)
,方法2的时间复杂度为O(Nlog N)
。正如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))