You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将IP地址列表按唯一网段合并为主机地址范围

解决方案

完整实现代码

import socket
import struct
from collections import defaultdict

# 原始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数值排序(你已实现的部分)
sorted_ips = sorted(ips, key=lambda ip: struct.unpack("!L", socket.inet_aton(ip))[0])

# 按网段分组:键为"前三个段"的字符串,值为该网段下的IP列表
network_groups = defaultdict(list)
for ip in sorted_ips:
    parts = ip.split('.')
    network = '.'.join(parts[:3])  # 提取/24网段标识
    network_groups[network].append(ip)

# 生成范围列表(字符串格式)
range_str_list = []
# 生成元组格式的范围列表
range_tuple_list = []

for net, ip_list in network_groups.items():
    min_ip = ip_list[0]
    max_ip = ip_list[-1]
    range_str_list.append(f"{min_ip}-{max_ip}")
    range_tuple_list.append((min_ip, max_ip))

# 输出结果
print("字符串格式的IP范围:")
print(range_str_list)
print("\n元组格式的IP范围:")
print(range_tuple_list)

代码说明

  1. IP排序:保留你已实现的基于socket.inet_aton和struct.unpack的排序逻辑,确保IP按数值从小到大排列,同一网段内的IP也会按顺序排列。
  2. 网段分组:
    • 使用defaultdict(list)自动创建网段对应的IP列表,避免手动判断网段是否存在。
    • 通过ip.split('.')拆分IP,取前三个部分拼接成网段标识(比如10.135.0),比正则表达式更简洁高效。
  3. 生成范围:
    • 因为IP已经排序,每个网段的IP列表第一个元素就是该网段的最小IP,最后一个元素就是最大IP。
    • 分别生成你需要的字符串格式和元组格式结果,单个IP的网段会自动生成首尾相同的范围。

运行结果

字符串格式的IP范围:
['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范围:
[('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,后续取首尾生成范围就非常直观,也避免了生成过多无效范围的问题。

内容的提问来源于stack exchange,提问作者Eric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 18:52:50