我有一个来自 API 调用的 IP 地址列表:
ips = ["10.135.0.80","10.135.0.81","10.135.0.83","10.135.1.200","10.135.1.220","10.160.150.2","10.160.150.7","10.255.255.2"]
我想要一个 IP 地址列表,如下所示:
ips = ["10.135.0.80-10.135.0.83","10.135.1.200-10.135.1.220","10.160.150.2-10.160.150.7","10.255.255.2-10.255.255.2"]
或基于 建议答案的结果:
ips = [("10.135.0.80", "10.135.0.83"),("10.135.1.200", "10.135.1.220"),("10.160.150.2", "10.160.150.7"),("10.255.255.2","10.255.255.2")]
如果网络地址相等,则连接最小到最大的主机地址。 如果每个网络地址有一个主机地址,则在所述主机地址之外创建一个范围。 如果网络地址不同,则启动一个新元素并重复。
我读过许多其他帖子,他们说使用套接字模块和按位运算符对 IP 地址进行排序,这就是原始 IP 列表的排序方式:
sortedAddresses = sorted(
ips, key=lambda ip: struct.unpack("!L", inet_aton(ip))[0]
)
我可以使用一些正则表达式轻松地将网络粉碎在一起,并使它们都独一无二:
net = []
host = []
for ip in sortedAddresses:
l = re.split("(.*)\\.(.*)\\.(.*)\\.(.*)", ip)
net.append(l[1:-2])
host.append(l[4:-1])
networks = []
for l in net:
if l not in networks:
networks.append(l)
hosts = []
for l in host:
for e in l:
hosts.append(e)
print(networks)
print(hosts)
印刷网络:
[['10', '135', '0'], ['10', '135', '1'], ['10', '160', '150'], ['10', '255', '255']]
打印主机:
['80', '81', '83', '200', '220', '2', '7', '2']
我认为 Joran 的答案here与套接字模块是我发现的最接近我的解决方案的东西。我只是不知道如何对主机列表进行排序以确定原始列表或主机列表中的开始和结束。
我在发帖前收到的建议答案也很接近,只是它会创建很多范围。我希望每个范围的网络地址都是唯一的。
以下代码:
import itertools
ips = [
"10.135.0.80",
"10.135.0.81",
"10.135.0.83",
"10.135.1.200",
"10.135.1.220",
"10.160.150.2",
"10.160.150.7",
"10.255.255.2",
]
for _, v in itertools.groupby(ips, lambda v: v.split(".")[:3]):
v = sorted(list(v))
low = v[0]
high = v[-1]
print(f"{low}-{high}")
输出:
10.135.0.80-10.135.0.83
10.135.1.200-10.135.1.220
10.160.150.2-10.160.150.7
10.255.255.2-10.255.255.2