Skip to content

Python で ipv6 address 表現#

ipv6 address の インクリメントは整数型で increment可能

ipv6 = ipaddress.ip_address('4001:1::1')
print(ipv6)
print(ipv6 +1)

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 を整数で計算

参考サイト#