Python中如何计算和处理子网掩码?

输入 172.14.0.0/24,返回数组从 172.14.1.1-172.14.254.254

怎么实现这种效果?


Python中如何计算和处理子网掩码?
11 回复
import ipaddress

def calculate_subnet_info(ip_with_cidr):
    """
    计算子网掩码、网络地址、广播地址等关键信息
    """
    try:
        # 解析CIDR表示法(如:192.168.1.0/24)
        network = ipaddress.ip_network(ip_with_cidr, strict=False)
        
        # 获取子网掩码
        subnet_mask = network.netmask
        
        # 获取网络地址
        network_address = network.network_address
        
        # 获取广播地址
        broadcast_address = network.broadcast_address
        
        # 获取可用主机范围
        hosts = list(network.hosts())
        first_host = hosts[0] if hosts else None
        last_host = hosts[-1] if hosts else None
        
        # 获取主机数量
        num_hosts = network.num_addresses - 2  # 减去网络地址和广播地址
        
        return {
            'subnet_mask': str(subnet_mask),
            'network_address': str(network_address),
            'broadcast_address': str(broadcast_address),
            'first_host': str(first_host) if first_host else 'N/A',
            'last_host': str(last_host) if last_host else 'N/A',
            'total_hosts': num_hosts,
            'cidr_notation': f"/{network.prefixlen}"
        }
        
    except ValueError as e:
        return f"输入格式错误: {e}"

def cidr_to_subnet_mask(cidr):
    """将CIDR前缀长度转换为点分十进制子网掩码"""
    if not 0 <= cidr <= 32:
        return "CIDR必须在0-32之间"
    
    mask = (0xffffffff << (32 - cidr)) & 0xffffffff
    return f"{(mask >> 24) & 0xff}.{(mask >> 16) & 0xff}.{(mask >> 8) & 0xff}.{mask & 0xff}"

def subnet_mask_to_cidr(mask_str):
    """将子网掩码转换为CIDR前缀长度"""
    try:
        mask = ipaddress.IPv4Address(mask_str)
        # 计算二进制中1的个数
        binary_str = bin(int(mask))[2:].zfill(32)
        return binary_str.count('1')
    except Exception as e:
        return f"转换失败: {e}"

def check_ip_in_subnet(ip_str, network_str):
    """检查IP是否属于某个子网"""
    try:
        ip = ipaddress.ip_address(ip_str)
        network = ipaddress.ip_network(network_str, strict=False)
        return ip in network
    except Exception as e:
        return f"检查失败: {e}"

# 使用示例
if __name__ == "__main__":
    # 示例1: 计算子网信息
    result = calculate_subnet_info("192.168.1.0/24")
    print("子网信息:")
    for key, value in result.items():
        print(f"  {key}: {value}")
    
    print("\n" + "="*50 + "\n")
    
    # 示例2: CIDR转子网掩码
    cidr = 24
    mask = cidr_to_subnet_mask(cidr)
    print(f"CIDR /{cidr} 对应的子网掩码: {mask}")
    
    # 示例3: 子网掩码转CIDR
    cidr_value = subnet_mask_to_cidr("255.255.255.0")
    print(f"子网掩码 255.255.255.0 对应的CIDR: /{cidr_value}")
    
    # 示例4: 检查IP是否在子网内
    check_result = check_ip_in_subnet("192.168.1.100", "192.168.1.0/24")
    print(f"IP 192.168.1.100 在子网 192.168.1.0/24 中: {check_result}")

这个代码提供了完整的子网掩码处理功能。主要包含:

  1. calculate_subnet_info() - 核心函数,输入CIDR格式(如192.168.1.0/24),返回子网掩码、网络地址、广播地址、可用主机范围等信息

  2. cidr_to_subnet_mask() - 将CIDR前缀长度(如24)转换为点分十进制子网掩码(255.255.255.0)

  3. subnet_mask_to_cidr() - 反向转换,子网掩码转CIDR前缀长度

  4. check_ip_in_subnet() - 检查指定IP是否属于某个子网

关键点:

  • 使用Python内置的ipaddress模块,这是处理IP地址和子网的标准库
  • 支持IPv4地址处理
  • 自动计算可用主机数量和范围
  • 包含完整的错误处理

直接复制代码就能用,记得根据需要调整输入参数。

用标准库别自己造轮子。


好的谢谢,我去看看。

才发现,楼主掩码写的不对
172.14.0.0/24 = 172.14.0.1~172.14.0.255
172.14.0.0/16 = 172.14.0.1~172.14.255.255

netaddr 了解一下

如果是 Python3 的话,官方的 ipaddress 库了解

python3<br>import ipaddress<br>first, *_, last = ipaddress.IPv4Network('172.14.0.0/24').hosts()<br>print('{} - {}'.format(first, last))<br>

额 刚刚在吃饭 打错了 不好意思

刚刚在吃饭,写错了 不好意思。

首先,172.14.0.0/24 应该是 172.14.0.0-172.14.0.255
然后用 ipaddress 就可以搞定了啊

python<br>def every_addr(ip_range):<br> import ipaddress<br> ipn = ipaddress.IPv4Network(ip_range)<br> return [ipn.network_address + i for i in range(0, 2 ** (32 - ipn._prefixlen))]<br>

#4
>才发现,楼主掩码写的不对
>172.14.0.0/24 = 172.14.0.1~172.14.0.255
>172.14.0.0/16 = 172.14.0.1~172.14.255.255

LZ 的要求应该是可用 IP 吧。
一个网段最后的 .255 是广播位,不可用。

没好好看过文档的不知道有 hosts 这玩意真惭愧…

如果不要广播地址和网络号,取 broadcast_address 和 network_address 按需跳过就好啦

ipaddress 库?

回到顶部