将 IP 地址列表排序为具有主机地址范围的唯一网络地址

问题描述 投票:0回答:1

我有一个来自 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与套接字模块是我发现的最接近我的解决方案的东西。我只是不知道如何对主机列表进行排序以确定原始列表或主机列表中的开始和结束。

我在发帖前收到的建议答案也很接近,只是它会创建很多范围。我希望每个范围的网络地址都是唯一的。

python ip-address
1个回答
0
投票

以下代码:

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
© www.soinside.com 2019 - 2024. All rights reserved.