【问题标题】:Why this code does not identify the class of an IP in some cases?为什么此代码在某些情况下无法识别 IP 的类别?
【发布时间】:2021-12-31 20:33:20
【问题描述】:

我编写了以下 Python 代码,用于对 IP 是否有效进行分类,如果有效则归类到它所属的类以及是否为私有:

from ipaddress import IPv4Address, IPv4Network, ip_address
import sys

try:
    ip = ip_address(sys.argv[1])
    print(f"{ip} is a correct IP{ip.version} address.")
    if ip_address(ip).is_private:
            print("It is a private IP.")
    classA = IPv4Network(("10.0.0.0", "255.0.0.0")) 
    classB = IPv4Network(("172.16.0.0", "255.240.0.0"))
    classC = IPv4Network(("192.168.0.0", "255.255.0.0")) 
    if ip in classA:
        print(f"{ip} is a correct class A IP{ip.version} address.")
        if ip_address(ip).is_private:
            print("It is a private IP.")
    elif ip in classB:
        print(f"{ip} is a correct class B IP{ip.version} address.")
        if ip_address(ip).is_private:
            print("It is a private IP.")
    elif ip in classC:
        print(f"{ip} is a correct class C IP{ip.version} address.") 
        if ip_address(ip).is_private:
            print("It is a private IP.")
except ValueError:
    print(f'address/netmask is invalid: {sys.argv[1]}')
except:
    print(f'Usage : {sys.argv[0]}  ip')

我假设that the range of A 类从1.0.0.0127.255.255.255,B 类从128.0.0.0191.255.255.255,C 类从192.0.0.0223.255.255.255。 当给定141.68.27.102 时,它不会 将类归类为 B(尽管the answer to this cisco lab does),为什么会这样? 当给定192.12.13.14时,它不会 将类归类为 C(虽然 the answer to this cisco lab does),为什么会这样?

【问题讨论】:

  • 摆脱那个裸露的except:处理程序——你永远不会知道在那个try块中发生了什么实际错误。
  • 为什么if ip_address(ip).is_private会重复? f"... IP{ip.version} address." 相同
  • @wjandrea 没有充分的理由,但这不是 OP 的重点:)
  • 172.32.255.255 位于 172.32.0.0/12 而不是 172.16.0.0/12 中以 172.31.255.255 结尾。同样192.168.0.0/16 永远不会包含192.12.*141.68.* 根本不是一个特殊的“私有”范围(并且不与您指定的任何类范围重叠)。
  • 您创建的三个IPv4Network 对象只包含每个类中的私有地址,而不是整个类(并不是说“类”的概念现在特别有意义)。例如,您的classC 仅涵盖 192.168.x.y;您的 192.12.13.14 示例显然不在该范围内。

标签: python ip-address python-ipaddress


【解决方案1】:

简短的回答是“因为这些 IP 不属于您定义的类”。

您的程序的这种稍微简化的返工首先打印出类,因此您可以看到您是如何定义它们的......以及为什么它们似乎不正确匹配。

from ipaddress import IPv4Network, ip_address

classes = {
    "A": IPv4Network(("10.0.0.0", "255.0.0.0")),
    "B": IPv4Network(("172.16.0.0", "255.240.0.0")),
    "C": IPv4Network(("192.168.0.0", "255.255.0.0")),
}


def describe_ip(ip_str):
    ip = ip_address(ip_str)
    for class_name, network in classes.items():
        if ip in network:
            print(f"{ip} is a correct class {class_name} IP{ip.version} address.")
            break
    else:
        print(f"{ip} does not belong in any of the classes defined.")


print(classes)
describe_ip("172.32.255.255")
describe_ip("141.68.27.102")
describe_ip("192.12.13.14")
describe_ip("172.16.255.255")

输出类似于(最后一行证明 172.16. 地址确实符合您的 B 类定义)。

{'A': IPv4Network('10.0.0.0/8'), 'B': IPv4Network('172.16.0.0/12'), 'C': IPv4Network('192.168.0.0/16')}
172.32.255.255 does not belong in any of the classes defined.
141.68.27.102 does not belong in any of the classes defined.
192.12.13.14 does not belong in any of the classes defined.
172.16.255.255 is a correct class B IP4 address.

【讨论】:

  • 感谢您的回答。为什么172.32.255.255不是B类地址? (假设类的范围:128.0.0.0191.255.255.255)。我在我的问题中添加了对 Cisco 实验室的引用,其中声明 192.12.13.14 属于 C 类(我倾向于同意它们,因为我假设范围 192.0.0.0223.255.255.255)。您的回答必须有充分的理由 - 您应用的范围是否与我引用的范围不同?我已经修改了问题。
  • 我的答案中的 IP 范围定义是您的,我没有更改它们。我不登录就无法访问 Cisco 链接,所以我不知道他们是如何定义这些范围的。
猜你喜欢
  • 2019-12-18
  • 2012-04-01
  • 2016-06-21
  • 1970-01-01
  • 2014-07-21
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多