python解析ip范围,判断ip是否在ip范围内

目录

1. 背景

2. 代码使用示例

2.1 分割ip,横杠 (-) 的ip范围

2.2 判断ip在掩码(/)的范围内

2.3 判断ip在横杠(-)的范围内

2.3.1 格式:192.168.1.1-192.168.1.10

2.3.2 格式:192.168.1.1-10

2.3.3 格式 192.168-169.*.*

2.3.4 格式192.168.*.*或192.*.168.*等

3. 其他扩展

3.1 校验是否为ipv4/ipv6

3.2 判断一个网段/前缀是另一个的子网


1. 背景

各种各样的ip范围,ip通配符等等,判断ip是否符合在这些范围内,搜索耗时耗力,整理出来,后续使用直接复制,有更好用的备注留言

2. 代码使用示例

2.1 分割ip,横杠 (-) 的ip范围

#! -*- coding:utf-8 -*

def split_ip_range(range):
    """
    处理以下格式分割
    192.168.1.1-10   拆分成192.168.1.1-192.168.1.10
    192.168.1-10.*   拆分成192.168.1.*-192.168.10.*
    192.168-169.*.*  拆分成192.168.*.*-192.169.*.*
    192-193.168.*.*  拆分成192.168.*.*-193.168.*.*
    192.168.1.1-10   拆分成192.168.1.1-192.168.1.10
    192.168.1.1-192.168.1.10   拆分成192.168.1.1-192.168.1.10
    :param range:
    :return:
    """
    if "-" not in range:
        raise ValueError("处理不了其他格式的,拜拜")
    start, end = range.split("-")
    start_list, end_list = start.split("."), end.split(".")

    start_lenght = len(start_list)
    end_lenght = len(end_list)
    # 暂不简化,逻辑简洁
    if start_lenght == 1 and end_lenght == 4:
        ret_start = start_list + end_list[1:]
        ret_end = end_list
    elif start_lenght == 2 and end_lenght == 3:
        ret_start = start_list + end_list[1:]
        ret_end = start_list[:1] + end_list
    elif start_lenght == 3 and end_lenght == 2:
        ret_start = start_list + end_list[1:]
        ret_end = start_list[:2] + end_list
    elif start_lenght == 4 and end_lenght == 1:
        ret_start = start_list + end_list[1:]
        ret_end = start_list[:3] + end_list
    elif start_lenght == 4 and end_lenght == 4:
        ret_start = start_list
        ret_end = end_list
    else:
        raise ValueError("处理不了其他格式的,再见")
    return ",".join(ret_start), ",".join(ret_end)

if __name__ == '__main__':

    # 测试
    ranges = [
        "192-193.168.*.*",
        "192.168-169.*.*",
        "192.168.1-10.*",
        "192.168.1.1-10",
        "192.168.1.1-192.168.1.10"
    ]
    for v in ranges:
        print(f"{v},拆分后是:{split_ip_range(v)}")

2.2 判断ip在掩码(/)的范围内

import ipaddress


def is_ip_in_cidr(ip, cidr):
    """
    判断一个IP地址是否在一个CIDR掩码范围内。
    :param ip: 字符串格式的IP地址
    :param cidr: CIDR格式的网络地址(如 "192.168.1.0/24")
    :return: 如果IP地址在CIDR范围内返回True,否则返回False
    """
    try:
        # 创建一个IP地址对象
        ip_obj = ipaddress.ip_address(ip)
        # 创建一个网络对象
        network = ipaddress.ip_network(cidr, strict=False)
        # 检查IP地址是否在网络范围内
        return ip_obj in network
    except ValueError as e:
        print(f"Error parsing IP or CIDR: {e}")
        return False


# 测试用例
test_cases = [
    ("192.168.1.5", "192.168.1.0/24"),
    ("192.168.1.254", "192.168.1.0/24"),
    ("192.168.2.1", "192.168.1.0/24"),
    ("192.168.1.10", "192.168.1.8/29"),
    ("192.168.1.12", "192.168.1.8/29")
]

for ip, cidr in test_cases:
    print(f"{ip} 是否在 {cidr} 范围内?{is_ip_in_cidr(ip, cidr)}")

2.3 判断ip在横杠(-)的范围内

2.3.1 格式:192.168.1.1-192.168.1.10

支持ipv4, ipv6网段

import ipaddress

# 支持ipv4, ipv6
def is_ip_in_range(ip_range_str, ip_address_str):
    """
    判断一个IP地址是否在一个IP段内。
    参数:
    ip_range_str (str): IP段,格式为"start_ip-end_ip"。
    ip_address_str (str): 要检查的IP地址。
    返回:
    bool: 如果IP地址在IP段内,返回True;否则返回False。
    """
    try:
        # 将IP范围字符串拆分为起始IP和结束IP
        start_ip, end_ip = ip_range_str.split('-')

        # 将起始IP和结束IP以及要检查的IP地址转换为IP地址对象
        start_ip_address = ipaddress.ip_address(start_ip)
        end_ip_address = ipaddress.ip_address(end_ip)
        ip_to_check = ipaddress.ip_address(ip_address_str)

        # 判断IP地址是否在起始IP和结束IP之间
        return start_ip_address <= ip_to_check <= end_ip_address
    except Exception as e:
        # print(f"Error: {e}")
        return False

2.3.2 格式:192.168.1.1-10

1. 使用2.1的方法分割

2. 使用2.3.1的方法判断

2.3.3 格式 192.168-169.*.*

包含*号的

1. 使用2.1的方法分割

2. 分割后的起始ip,* 做转换

3. 使用2.3.1方法判断

# 开始ip的*换为0
# 结束ip的*换为255

ip_range_str = '192.*.1.1-192.*.10.1'  # 2.1方法返回

ip_range_str = '192.0.1.1-192.255.10.1'  # 修改
ip_str = '192.168.10.1'
print(is_ip_in_range(ip_range_str, ip_str))

2.3.4 格式192.168.*.*或192.*.168.*等

1. 先如下处理数据

2. 再调用2.3.1方法

ip = "192.168.*.*"

start = ip.replace("*", "0")
end = ip.replace("*", "255")
print(f"{start}-{end}")   # 192.0.0.1-192.255.255.1

3. 其他扩展

3.1 校验是否为ipv4/ipv6

import ipaddress

def validate_ip(ip_address: str):
    """
    校验是否为ipv4或ipv6
    @param ip_address: ip
    @return:
    """
    try:
        ipaddress.ip_address(ip_address)
        return True
    except ValueError:
        return False

3.2 判断一个网段/前缀是另一个的子网

import ipaddress

def is_subnet_of(a, b):
    """
    Returns True if network a is a subnet of network b.
    网络a是网络b的子网,返回true
    @param a: 子网
    @param b: 父网
    @return:  bool
    """

    try:
        # 将前缀转换为IP网络对象
        a_network = ipaddress.ip_network(a, strict=True)
        b_network = ipaddress.ip_network(b, strict=True)
        return (a_network.network_address >= b_network.network_address and
                a_network.broadcast_address <= b_network.broadcast_address)
    except Exception as e:
        print(e)
        return False

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值