每週一個 Python 模組 | ipaddress

yongxinz發表於2018-12-25

專欄地址:每週一個 Python 模組

ipaddress模組包括用於處理 IPv4 和 IPv6 網路地址的類。這些類支援驗證,查詢網路上的地址和主機以及其他常見操作。

地址

最基本的物件代表網路地址本身。傳遞字串,整數或位元組序列給 ip_address() 來構造地址。返回值是 IPv4AddressIPv6Address 例項,具體取決於所使用的地址型別。

import binascii
import ipaddress


ADDRESSES = [
    '10.9.0.6',
    'fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa',
]

for ip in ADDRESSES:
    addr = ipaddress.ip_address(ip)
    print('{!r}'.format(addr))
    print('   IP version:', addr.version)
    print('   is private:', addr.is_private)
    print('  packed form:', binascii.hexlify(addr.packed))
    print('      integer:', int(addr))
    print()
    
# output
# IPv4Address('10.9.0.6')
#    IP version: 4
#    is private: True
#   packed form: b'0a090006'
#       integer: 168361990
# 
# IPv6Address('fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa')
#    IP version: 6
#    is private: True
#   packed form: b'fdfd87b5b4755e3eb1bce121a8eb14aa'
#       integer: 337611086560236126439725644408160982186
複製程式碼

還可以用這個方法來校驗 IP 地址是否合法:

import ipaddress


def  is_ip_Valid(ipaddr):
    try:
        ipaddress.ip_address(ipaddr);
        return True;
    except :
        return False;
     
if __name__ == '__main__':
    print(is_ip_Valid('2001:db8::'));
    print(is_ip_Valid('192.168.168.1'));
複製程式碼

網路

網路是由一系列地址組成的,通常用地址和掩碼這種形式來表示。

import ipaddress

NETWORKS = [
    '10.9.0.0/24',
    'fdfd:87b5:b475:5e3e::/64',
]

for n in NETWORKS:
    net = ipaddress.ip_network(n)
    print('{!r}'.format(net))
    print('     is private:', net.is_private)
    print('      broadcast:', net.broadcast_address)
    print('     compressed:', net.compressed)
    print('   with netmask:', net.with_netmask)
    print('  with hostmask:', net.with_hostmask)
    print('  num addresses:', net.num_addresses)
    print()
    
# output
# IPv4Network('10.9.0.0/24')
#      is private: True
#       broadcast: 10.9.0.255
#      compressed: 10.9.0.0/24
#    with netmask: 10.9.0.0/255.255.255.0
#   with hostmask: 10.9.0.0/0.0.0.255
#   num addresses: 256
# 
# IPv6Network('fdfd:87b5:b475:5e3e::/64')
#      is private: True
#       broadcast: fdfd:87b5:b475:5e3e:ffff:ffff:ffff:ffff
#      compressed: fdfd:87b5:b475:5e3e::/64
#    with netmask: fdfd:87b5:b475:5e3e::/ffff:ffff:ffff:ffff::
#   with hostmask: fdfd:87b5:b475:5e3e::/::ffff:ffff:ffff:ffff
#   num addresses: 18446744073709551616
複製程式碼

與地址一樣,IPv4 和 IPv6網路有兩種網路類。每個類提供用於訪問與網路相關聯的值的屬性或方法,例如廣播地址和可供主機使用的網路上的地址。

網路例項是可迭代的,併產生網路上的地址。

import ipaddress

NETWORKS = [
    '10.9.0.0/24',
    'fdfd:87b5:b475:5e3e::/64',
]

for n in NETWORKS:
    net = ipaddress.ip_network(n)
    print('{!r}'.format(net))
    for i, ip in zip(range(3), net):
        print(ip)
    print()
    
# output
# IPv4Network('10.9.0.0/24')
# 10.9.0.0
# 10.9.0.1
# 10.9.0.2
# 
# IPv6Network('fdfd:87b5:b475:5e3e::/64')
# fdfd:87b5:b475:5e3e::
# fdfd:87b5:b475:5e3e::1
# fdfd:87b5:b475:5e3e::2
複製程式碼

此示例僅列印一些地址,因為 IPv6 網路可以包含的地址遠多於輸出中的地址。

迭代網路會產生地址,但並非所有地址都對主機有效。例如,網路的基地址和廣播地址。要查詢網路上常規主機可以使用的地址,請使用 hosts() 方法,該方法會生成一個生成器。

import ipaddress

NETWORKS = [
    '10.9.0.0/24',
    'fdfd:87b5:b475:5e3e::/64',
]

for n in NETWORKS:
    net = ipaddress.ip_network(n)
    print('{!r}'.format(net))
    for i, ip in zip(range(3), net.hosts()):
        print(ip)
    print()
    
# output
# IPv4Network('10.9.0.0/24')
# 10.9.0.1
# 10.9.0.2
# 10.9.0.3
# 
# IPv6Network('fdfd:87b5:b475:5e3e::/64')
# fdfd:87b5:b475:5e3e::1
# fdfd:87b5:b475:5e3e::2
# fdfd:87b5:b475:5e3e::3
複製程式碼

將此示例的輸出與前一示例進行比較表明,主機地址不包括在整個網路上進行迭代時生成的第一個值。

除了迭代器協議之外,網路還支援in 操作,來確定地址是否是網路的一部分。

import ipaddress


NETWORKS = [
    ipaddress.ip_network('10.9.0.0/24'),
    ipaddress.ip_network('fdfd:87b5:b475:5e3e::/64'),
]

ADDRESSES = [
    ipaddress.ip_address('10.9.0.6'),
    ipaddress.ip_address('10.7.0.31'),
    ipaddress.ip_address('fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa'),
    ipaddress.ip_address('fe80::3840:c439:b25e:63b0'),
]


for ip in ADDRESSES:
    for net in NETWORKS:
        if ip in net:
            print('{}\nis on {}'.format(ip, net))
            break
    else:
        print('{}\nis not on a known network'.format(ip))
    print()
    
# output
# 10.9.0.6
# is on 10.9.0.0/24
# 
# 10.7.0.31
# is not on a known network
# 
# fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa
# is on fdfd:87b5:b475:5e3e::/64
# 
# fe80::3840:c439:b25e:63b0
# is not on a known network
複製程式碼

in使用網路掩碼來測試地址,因此它比擴充套件網路上的完整地址列表更有效。

介面

網路介面表示網路上的特定地址,並且可以由主機地址和網路字首或網路掩碼錶示。

import ipaddress


ADDRESSES = [
    '10.9.0.6/24',
    'fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/64',
]


for ip in ADDRESSES:
    iface = ipaddress.ip_interface(ip)
    print('{!r}'.format(iface))
    print('network:\n  ', iface.network)
    print('ip:\n  ', iface.ip)
    print('IP with prefixlen:\n  ', iface.with_prefixlen)
    print('netmask:\n  ', iface.with_netmask)
    print('hostmask:\n  ', iface.with_hostmask)
    print()
    
# output
# IPv4Interface('10.9.0.6/24')
# network:
#    10.9.0.0/24
# ip:
#    10.9.0.6
# IP with prefixlen:
#    10.9.0.6/24
# netmask:
#    10.9.0.6/255.255.255.0
# hostmask:
#    10.9.0.6/0.0.0.255
# 
# IPv6Interface('fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/64')
# network:
#    fdfd:87b5:b475:5e3e::/64
# ip:
#    fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa
# IP with prefixlen:
#    fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/64
# netmask:
#    fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/ffff:ffff:ffff:ffff::
# hostmask:
#    fdfd:87b5:b475:5e3e:b1bc:e121:a8eb:14aa/::ffff:ffff:ffff:ffff
複製程式碼

介面物件具有分別訪問完整網路和地址的屬性,以及表達介面和網路掩碼的幾種不同方式。

相關文件:

pymotw.com/3/ipaddress…

相關文章