Skip to main content

21.28. ipaddress — IPv4/IPv6操作库

源代码: Lib/ipaddress.py


ipaddress 提供创建,操作和操作IPv4和IPv6地址和网络的功能。

此模块中的函数和类可以直接处理与IP地址相关的各种任务,包括检查两个主机是否在同一子网上,遍历特定子网中的所有主机,检查字符串是否表示有效IP地址或网络定义等。

这是完整的模块API参考 - 有关概述和介绍,请参阅 ipaddress模块介绍

3.3 新版功能.

21.28.1. 便利工厂功能

ipaddress 模块提供了出厂功能,可方便地创建IP地址,网络和接口:

ipaddress.ip_address(address)

根据作为参数传递的IP地址返回 IPv4AddressIPv6Address 对象。可以提供IPv4或IPv6地址;默认情况下,小于2 ** 32的整数将被视为IPv4。如果 address 不表示有效的IPv4或IPv6地址,则引发 ValueError

>>> ipaddress.ip_address('192.168.0.1')
IPv4Address('192.168.0.1')
>>> ipaddress.ip_address('2001:db8::')
IPv6Address('2001:db8::')
ipaddress.ip_network(address, strict=True)

根据作为参数传递的IP地址返回 IPv4NetworkIPv6Network 对象。 address 是表示IP网络的字符串或整数。可以提供IPv4或IPv6网络;默认情况下,小于2 ** 32的整数将被视为IPv4。 strict 被传递给 IPv4NetworkIPv6Network 构造函数。如果 address 不表示有效的IPv4或IPv6地址,或者如果网络已设置主机位,则引发 ValueError

>>> ipaddress.ip_network('192.168.0.0/28')
IPv4Network('192.168.0.0/28')
ipaddress.ip_interface(address)

根据作为参数传递的IP地址返回 IPv4InterfaceIPv6Interface 对象。 address 是表示IP地址的字符串或整数。可以提供IPv4或IPv6地址;默认情况下,小于2 ** 32的整数将被视为IPv4。如果 address 不表示有效的IPv4或IPv6地址,则引发 ValueError

这些便利功能的一个缺点是,需要处理IPv4和IPv6格式意味着错误消息提供关于精确错误的最少信息,因为功能不知道IPv4或IPv6格式是否是预期的。可以通过直接调用适当的特定于类的构造函数来获取更详细的错误报告。

21.28.2. IP地址

21.28.2.1. 地址对象

IPv4AddressIPv6Address 对象共享很多公共属性。一些仅对IPv6地址有意义的属性也由 IPv4Address 对象实现,以便更容易编写正确处理两个IP版本的代码。

class ipaddress.IPv4Address(address)

构造IPv4地址。如果 address 不是有效的IPv4地址,则会引发 AddressValueError

以下构成有效的IPv4地址:

  1. 以十进制小数点符号表示的字符串,由四个十进制整数组成,包含范围0–255,由点(例如 192.168.0.1)分隔。每个整数表示地址中的八位字节(字节)。只有小于8的值才允许前导零(因为在这样的字符串的十进制和八进制解释之间没有歧义)。

  2. 适合32位的整数。

  3. 封装到长度为4(最高有效字节优先)的 bytes 对象中的整数。

>>> ipaddress.IPv4Address('192.168.0.1')
IPv4Address('192.168.0.1')
>>> ipaddress.IPv4Address(3232235521)
IPv4Address('192.168.0.1')
>>> ipaddress.IPv4Address(b'\xC0\xA8\x00\x01')
IPv4Address('192.168.0.1')
version

适当的版本号:4 用于IPv4,6 用于IPv6。

max_prefixlen

此版本的地址表示中的总位数:32 表示IPv4,128 表示IPv6。

前缀定义了地址中前导比特的数量,这些比特被比较以确定地址是否是网络的一部分。

compressed
exploded

点分十进制符号的字符串表示形式。前导零从不包括在表示中。

由于IPv4没有为八位字节设置为零的地址定义速记符号,因此这两个属性总是与IPv4地址的 str(addr) 相同。暴露这些属性使得编写能够处理IPv4和IPv6地址的显示代码变得更容易。

packed

此地址的二进制表示 - 适当长度的 bytes 对象(最高有效字节优先)。 IPv4为4字节,IPv6为16字节。

reverse_pointer

IP地址的反向DNS PTR记录的名称,例如。:

>>> ipaddress.ip_address("127.0.0.1").reverse_pointer
'1.0.0.127.in-addr.arpa'
>>> ipaddress.ip_address("2001:db8::1").reverse_pointer
'1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa'

这是可用于执行PTR查找的名称,而不是解析的主机名本身。

3.5 新版功能.

is_multicast

True,如果地址保留供多播使用。请参阅 RFC 3171 (对于IPv4)或 RFC 2373 (对于IPv6)。

is_private

True,如果地址分配给专用网络。请参阅 iana-ipv4-special-registry (对于IPv4)或 iana-ipv6-special-registry (对于IPv6)。

is_global

True 如果地址分配给公共网络。请参阅 iana-ipv4-special-registry (对于IPv4)或 iana-ipv6-special-registry (对于IPv6)。

3.4 新版功能.

is_unspecified

True 如果地址未指定。请参阅 RFC 5735 (对于IPv4)或 RFC 2373 (对于IPv6)。

is_reserved

True 如果地址否则为IETF保留。

is_loopback

True 如果这是一个环回地址。请参阅 RFC 3330 (对于IPv4)或 RFC 2373 (对于IPv6)。

True,如果地址被保留用于链路本地使用。参见 RFC 3927

class ipaddress.IPv6Address(address)

构造IPv6地址。如果 address 不是有效的IPv6地址,则会引发 AddressValueError

以下构成有效的IPv6地址:

  1. 一个由8组四个十六进制数字组成的字符串,每组代表16位。组由冒号分隔。这描述了 exploded (长符)符号。字符串也可以通过各种方式为 compressed (简写符号)。有关详细信息,请参阅 RFC 4291。例如,"0000:0000:0000:0000:0000:0abc:0007:0def" 可以被压缩为 "::abc:7:def"

  2. 适合128位的整数。

  3. 一个整数打包成长度为16的 bytes 对象,big-endian。

>>> ipaddress.IPv6Address('2001:db8::1000')
IPv6Address('2001:db8::1000')
compressed

地址表示的短形式,其中组中的前导零被省略并且组的最长序列完全由零组成,折叠到单个空组。

这也是 str(addr) 为IPv6地址返回的值。

exploded

长地址表示形式,所有前导零和组完全由零组成。

对于以下属性,请参阅 IPv4Address 类的相应文档:

packed
reverse_pointer
version
max_prefixlen
is_multicast
is_private
is_global
is_unspecified
is_reserved
is_loopback

3.4 新版功能: is_global

is_site_local

True,如果地址保留为站点本地使用。请注意,站点本地地址空间已被 RFC 3879 弃用。使用 is_private 来测试这个地址是否在 RFC 4193 定义的唯一本地地址空间中。

ipv4_mapped

对于看起来是IPv4映射地址(以 ::FFFF/96 开头)的地址,此属性将报告嵌入的IPv4地址。对于任何其他地址,此属性将是 None

sixtofour

对于看起来是由 RFC 3056 定义的6to4地址(以 2002::/16 开头)的地址,此属性将报告嵌入式IPv4地址。对于任何其他地址,此属性将是 None

teredo

对于看起来是由 RFC 4380 定义的Teredo地址(以 2001::/32 开头)的地址,此属性将报告嵌入式 (server, client) IP地址对。对于任何其他地址,此属性将是 None

21.28.2.2. 转换为字符串和整数

要与网络接口(如套接字模块)互操作,地址必须转换为字符串或整数。这是使用 str()int() 内置函数处理的:

>>> str(ipaddress.IPv4Address('192.168.0.1'))
'192.168.0.1'
>>> int(ipaddress.IPv4Address('192.168.0.1'))
3232235521
>>> str(ipaddress.IPv6Address('::1'))
'::1'
>>> int(ipaddress.IPv6Address('::1'))
1

21.28.2.3. 操作员

地址对象支持一些操作符。除非另有说明,运营商只能在兼容对象(即IPv4与IPv4,IPv6与IPv6)之间应用。

21.28.2.3.1. 比较运算符

地址对象可以与通常的一组比较运算符进行比较。一些例子:

>>> IPv4Address('127.0.0.2') > IPv4Address('127.0.0.1')
True
>>> IPv4Address('127.0.0.2') == IPv4Address('127.0.0.1')
False
>>> IPv4Address('127.0.0.2') != IPv4Address('127.0.0.1')
True

21.28.2.3.2. 算术运算符

整数可以添加到地址对象或从地址对象中减去。一些例子:

>>> IPv4Address('127.0.0.2') + 3
IPv4Address('127.0.0.5')
>>> IPv4Address('127.0.0.2') - 3
IPv4Address('126.255.255.255')
>>> IPv4Address('255.255.255.255') + 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ipaddress.AddressValueError: 4294967296 (>= 2**32) is not permitted as an IPv4 address

21.28.3. IP网络定义

IPv4NetworkIPv6Network 对象提供了一种用于定义和检查IP网络定义的机制。网络定义由 mask网络地址 组成,并且因此定义了当与掩码进行掩码(二进制AND)时等于网络地址的IP地址范围。例如,具有掩码 255.255.255.0 和网络地址 192.168.1.0 的网络定义由包括在范围 192.168.1.0192.168.1.255 中的IP地址组成。

21.28.3.1. 前缀,网络掩码和主机掩码

有几种等效的方法来指定IP网络掩码。 prefix /<nbits> 是表示在网络掩码中设置了多少高阶比特的符号。 网掩码 是设置了一些数量的高阶位的IP地址。因此,前缀 /24 等效于IPv4中的净掩码 255.255.255.0 或IPv6中的 ffff:ff00::。此外,主机掩码网掩码 的逻辑反,并且有时(例如在思科访问控制列表中)用于表示网络掩码。在IPv4中等同于 /24 的主机掩码是 0.0.0.255

21.28.3.2. 网络对象

地址对象实现的所有属性也由网络对象实现。此外,网络对象实现附加属性。所有这些在 IPv4NetworkIPv6Network 之间是常见的,因此为了避免重复,它们仅记录用于 IPv4Network

class ipaddress.IPv4Network(address, strict=True)

构造IPv4网络定义。 address 可以是以下之一:

  1. 由IP地址和可选掩码组成的字符串,由斜杠(/)分隔。 IP地址是网络地址,掩码可以是单个数字,这意味着它是 prefix,或IPv4地址的字符串表示形式。如果是后者,则掩码被解释为 网掩码,如果它以非零字段开始,或者如果它以零字段开始,则被解释为 主机掩码。如果没有提供掩码,它被认为是 /32

    例如,以下 address 规范是等效的:192.168.1.0/24192.168.1.0/255.255.255.0192.168.1.0/0.0.0.255

  2. 适合32位的整数。这相当于单地址网络,网络地址为 address,掩码为 /32

  3. 一个整数打包成长度为4的 bytes 对象,big-endian。解释类似于整数 address

  4. 地址描述和网络掩码的二元组,其中地址描述是字符串,32位整数,4字节打包整数或现有IPv4Address对象;并且网络掩码是表示前缀长度(例如,24)的整数或表示前缀掩码(例如 255.255.255.0)的串。

如果 address 不是有效的IPv4地址,则会引发 AddressValueError。如果掩码对IPv4地址无效,则引发 NetmaskValueError

如果 strictTrue,并且在提供的地址中设置了主机位,则 ValueError 被引发。否则,主机位被屏蔽以确定适当的网络地址。

除非另有说明,否则接受其他网络/地址对象的所有网络方法将产生 TypeError,如果参数的IP版本与 self 不兼容

在 3.5 版更改: 添加了 address 构造函数参数的二元组形式。

version
max_prefixlen

请参阅 IPv4Address 中的相应属性文档

is_multicast
is_private
is_unspecified
is_reserved
is_loopback

这些属性对于网络作为一个整体是真的,如果它们对网络地址和广播地址都是真的

network_address

网络的网络地址。网络地址和前缀长度一起唯一地定义网络。

broadcast_address

网络的广播地址。发送到广播地址的数据包应该由网络上的每个主机接收。

hostmask

主机掩码,作为字符串。

with_prefixlen
compressed
exploded

网络的字符串表示,带有前缀符号的掩码。

with_prefixlencompressed 总是与 str(network) 相同。 exploded 使用爆炸形式的网络地址。

with_netmask

网络的字符串表示,带有网络掩码符号的掩码。

with_hostmask

网络的字符串表示,在主机掩码符号中带有掩码。

num_addresses

网络中的地址总数。

prefixlen

网络前缀的长度(以位为单位)。

hosts()

在网络中的可用主机上返回迭代器。可用主机是属于网络的所有IP地址,除了网络地址本身和网络广播地址。

>>> list(ip_network('192.0.2.0/29').hosts())  
[IPv4Address('192.0.2.1'), IPv4Address('192.0.2.2'),
 IPv4Address('192.0.2.3'), IPv4Address('192.0.2.4'),
 IPv4Address('192.0.2.5'), IPv4Address('192.0.2.6')]
overlaps(other)

True,如果此网络部分或全部包含在 otherother 中,则完全包含在此网络中。

address_exclude(network)

计算从此表中删除给定 network 所产生的网络定义。返回网络对象的迭代器。如果 network 未完全包含在此网络中,则提高 ValueError

>>> n1 = ip_network('192.0.2.0/28')
>>> n2 = ip_network('192.0.2.1/32')
>>> list(n1.address_exclude(n2))  
[IPv4Network('192.0.2.8/29'), IPv4Network('192.0.2.4/30'),
 IPv4Network('192.0.2.2/31'), IPv4Network('192.0.2.0/32')]
subnets(prefixlen_diff=1, new_prefix=None)

根据参数值,加入以进行当前网络定义的子网。 prefixlen_diff 是我们的前缀长度应该增加的量。 new_prefix 是子网的所需新前缀;它必须大于我们的前缀。必须设置 prefixlen_diffnew_prefix 中的一个且仅有一个。返回网络对象的迭代器。

>>> list(ip_network('192.0.2.0/24').subnets())
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/25')]
>>> list(ip_network('192.0.2.0/24').subnets(prefixlen_diff=2))  
[IPv4Network('192.0.2.0/26'), IPv4Network('192.0.2.64/26'),
 IPv4Network('192.0.2.128/26'), IPv4Network('192.0.2.192/26')]
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=26))  
[IPv4Network('192.0.2.0/26'), IPv4Network('192.0.2.64/26'),
 IPv4Network('192.0.2.128/26'), IPv4Network('192.0.2.192/26')]
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=23))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    raise ValueError('new prefix must be longer')
ValueError: new prefix must be longer
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=25))
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/25')]
supernet(prefixlen_diff=1, new_prefix=None)

包含此网络定义的超集,取决于参数值。 prefixlen_diff 是我们的前缀长度应该减少的量。 new_prefix 是所需的新的超前缀;它必须小于我们的前缀。必须设置 prefixlen_diffnew_prefix 中的一个且仅有一个。返回单个网络对象。

>>> ip_network('192.0.2.0/24').supernet()
IPv4Network('192.0.2.0/23')
>>> ip_network('192.0.2.0/24').supernet(prefixlen_diff=2)
IPv4Network('192.0.0.0/22')
>>> ip_network('192.0.2.0/24').supernet(new_prefix=20)
IPv4Network('192.0.0.0/20')
compare_networks(other)

将此网络与 other 进行比较。在这个比较中,仅考虑网络地址;主机位不是。返回 -101

>>> ip_network('192.0.2.1/32').compare_networks(ip_network('192.0.2.2/32'))
-1
>>> ip_network('192.0.2.1/32').compare_networks(ip_network('192.0.2.0/32'))
1
>>> ip_network('192.0.2.1/32').compare_networks(ip_network('192.0.2.1/32'))
0
class ipaddress.IPv6Network(address, strict=True)

构造IPv6网络定义。 address 可以是以下之一:

  1. 由IP地址和可选掩码组成的字符串,由斜杠(/)分隔。 IP地址是网络地址,掩码可以是单个数字,这意味着它是 prefix 或IPv6地址的字符串表示形式。如果是后者,则掩码被解释为 网掩码。如果没有提供掩码,它被认为是 /128

    例如,以下 address 规范是等效的:2001:db00::0/242001:db00::0/ffff:ff00::

  2. 适合128位的整数。这相当于单地址网络,网络地址为 address,掩码为 /128

  3. 一个整数打包成长度为16的 bytes 对象,big-endian。解释类似于整数 address

  4. 地址描述和网络掩码的二元组,其中地址描述是字符串,128位整数,16字节打包整数或现有的IPv6地址对象;并且网络掩码是表示前缀长度的整数。

如果 address 不是有效的IPv6地址,则会引发 AddressValueError。如果掩码对IPv6地址无效,则引发 NetmaskValueError

如果 strictTrue,并且在提供的地址中设置了主机位,则 ValueError 被引发。否则,主机位被屏蔽以确定适当的网络地址。

在 3.5 版更改: 添加了 address 构造函数参数的二元组形式。

version
max_prefixlen
is_multicast
is_private
is_unspecified
is_reserved
is_loopback
network_address
broadcast_address
hostmask
with_prefixlen
compressed
exploded
with_netmask
with_hostmask
num_addresses
prefixlen
hosts()
overlaps(other)
address_exclude(network)
subnets(prefixlen_diff=1, new_prefix=None)
supernet(prefixlen_diff=1, new_prefix=None)
compare_networks(other)

请参阅 IPv4Network 中的相应属性文档

is_site_local

如果网络地址和广播地址都是真的,那么这些属性对于网络作为整体是真的

21.28.3.3. 操作员

网络对象支持一些运算符。除非另有说明,运营商只能在兼容对象(即IPv4与IPv4,IPv6与IPv6)之间应用。

21.28.3.3.1. 逻辑运算符

网络对象可以与通常的一组逻辑运算符进行比较,类似于地址对象。

21.28.3.3.2. 迭代

可以迭代网络对象以列出属于网络的所有地址。对于迭代,返回 all 主机,包括不可用的主机(对于可用的主机,使用 hosts() 方法)。一个例子:

>>> for addr in IPv4Network('192.0.2.0/28'):
...     addr
...
IPv4Address('192.0.2.0')
IPv4Address('192.0.2.1')
IPv4Address('192.0.2.2')
IPv4Address('192.0.2.3')
IPv4Address('192.0.2.4')
IPv4Address('192.0.2.5')
IPv4Address('192.0.2.6')
IPv4Address('192.0.2.7')
IPv4Address('192.0.2.8')
IPv4Address('192.0.2.9')
IPv4Address('192.0.2.10')
IPv4Address('192.0.2.11')
IPv4Address('192.0.2.12')
IPv4Address('192.0.2.13')
IPv4Address('192.0.2.14')
IPv4Address('192.0.2.15')

21.28.3.3.3. 网络作为地址的容器

网络对象可以充当地址的容器。一些例子:

>>> IPv4Network('192.0.2.0/28')[0]
IPv4Address('192.0.2.0')
>>> IPv4Network('192.0.2.0/28')[15]
IPv4Address('192.0.2.15')
>>> IPv4Address('192.0.2.6') in IPv4Network('192.0.2.0/28')
True
>>> IPv4Address('192.0.3.6') in IPv4Network('192.0.2.0/28')
False

21.28.4. 接口对象

class ipaddress.IPv4Interface(address)

构造IPv4接口。 address 的含义与 IPv4Network 的构造函数相同,除了始终接受任意主机地址。

IPv4InterfaceIPv4Address 的子类,因此它继承了该类的所有属性。此外,还有以下属性可用:

ip

没有网络信息的地址(IPv4Address)。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.ip
IPv4Address('192.0.2.5')
network

此接口所属的网络(IPv4Network)。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.network
IPv4Network('192.0.2.0/24')
with_prefixlen

带有掩码的接口的字符串表示形式,以前缀符号表示。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.with_prefixlen
'192.0.2.5/24'
with_netmask

将网络接口的字符串表示形式作为网络掩码。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.with_netmask
'192.0.2.5/255.255.255.0'
with_hostmask

以网络作为主机掩码的接口的字符串表示形式。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.with_hostmask
'192.0.2.5/0.0.0.255'
class ipaddress.IPv6Interface(address)

构造IPv6接口。 address 的含义与 IPv6Network 的构造函数相同,除了始终接受任意主机地址。

IPv6InterfaceIPv6Address 的子类,因此它继承了该类的所有属性。此外,还有以下属性可用:

ip
network
with_prefixlen
with_netmask
with_hostmask

请参阅 IPv4Interface 中的相应属性文档。

21.28.5. 其他模块级功能

该模块还提供以下模块级功能:

ipaddress.v4_int_to_packed(address)

将地址表示为网络(big-endian)顺序中的4个打包字节。 address 是IPv4 IP地址的整数表示。如果整数为负或太大而不能成为IPv4 IP地址,则会引发 ValueError

>>> ipaddress.ip_address(3221225985)
IPv4Address('192.0.2.1')
>>> ipaddress.v4_int_to_packed(3221225985)
b'\xc0\x00\x02\x01'
ipaddress.v6_int_to_packed(address)

将地址表示为网络(big-endian)顺序中的16个打包字节。 address 是IPv6 IP地址的整数表示。如果整数为负或太大而不是IPv6 IP地址,则会引发 ValueError

ipaddress.summarize_address_range(first, last)

返回给定第一个和最后一个IP地址的汇总网络范围的迭代器。 first 是范围内的第一个 IPv4AddressIPv6Addresslast 是范围内的最后一个 IPv4AddressIPv6Address。如果 firstlast 不是IP地址或不是相同版本,则会引发 TypeError。如果 last 不大于 firstfirst 地址版本不是4或6,则会引发 ValueError

>>> [ipaddr for ipaddr in ipaddress.summarize_address_range(
...    ipaddress.IPv4Address('192.0.2.0'),
...    ipaddress.IPv4Address('192.0.2.130'))]
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), IPv4Network('192.0.2.130/32')]
ipaddress.collapse_addresses(addresses)

返回折叠的 IPv4NetworkIPv6Network 对象的迭代器。 addressesIPv4NetworkIPv6Network 对象的迭代器。如果 addresses 包含混合版本对象,则引发 TypeError

>>> [ipaddr for ipaddr in
... ipaddress.collapse_addresses([ipaddress.IPv4Network('192.0.2.0/25'),
... ipaddress.IPv4Network('192.0.2.128/25')])]
[IPv4Network('192.0.2.0/24')]
ipaddress.get_mixed_type_key(obj)

返回适用于在网络和地址之间排序的键。地址和网络对象默认不可排序;他们根本不同,所以表达:

IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24')

没有意义。有些时候,你可能希望有 ipaddress 排序这些反正。如果需要这样做,您可以使用此函数作为 sorted()key 参数。

obj 是网络或地址对象。

21.28.6. 自定义例外

为了支持来自类构造函数的更具体的错误报告,模块定义了以下异常:

exception ipaddress.AddressValueError(ValueError)

与地址相关的任何值错误。

exception ipaddress.NetmaskValueError(ValueError)

与网络掩码相关的任何值错误。