Python で ipv6 address 表現#
ipv6 address の インクリメントは整数型で increment可能
ipv6 network アドレスは <class 'ipaddress.IPv6Address'>
のため 整数型でのインクリメントはTypeError
となる
ipv6_nw = ipaddress.ip_network('4001:1::/64')
print(type(ipv6_nw))
# <class 'ipaddress.IPv6Address'>
print(ipv6_nw)
print(ipv6_nw +1)
# TypeError: unsupported operand type(s) for +: 'IPv6Network' and 'int'
標準のpythonパッケージを使用して、IPv6 ネットワークアドレスをインクリメントする方法は以下のとおり
import ipaddress import itertools as it class BetterIPv6Network(ipaddress.IPv6Network): def __add__(self, offset): """Add numeric offset to the IP.""" new_base_addr = int(self.network_address) + offset return self.__class__((new_base_addr, self.prefixlen)) def size(self): """Return network size.""" return 1 << (self.max_prefixlen - self.prefixlen) network = BetterIPv6Network('4001:1::/32') network_addrs = (network + i * network.size() for i in it.count()) print(next(network_addrs)) print(next(network_addrs)) print(next(network_addrs))
解説#
ipaddress.IPv6Network
クラスを継承して、インクリメント可能な IPv6Network クラスを定義new_base_addr
では ipv6 address を整数型(10進数)へ変換し、offset (network.size() × it.count()で生成した値)を足している__add__
にて+
演算子使用時に呼び出されるメソッドを実装itertools.count()
を用いて、無限にカウントアップまたはカウントダウンする値を返すイテレータを生成itertools.count()
はデフォルトは開始値が0で1ずつ増加するため ネットワークアドレスをnext関数で呼び出すと、1ずつインクリメントされた値が返されるnetwork.size()
で ipaddress を整数で計算