はじめに
タイトルのとおり、Pythonで「192.168.1.100」のようなIPアドレスの文字列が正しいフォーマットか確認する簡単なやり方のメモです。以前は正規表現をがんばって書いていました。
やりかた
from socket import inet_aton
def is_valid_ip(addr):
try:
inet_aton(addr)
return True
except:
return False
is_valid_ip("192.168.1.100") # True
is_valid_ip("192.168.1.xxx") # False
以下のライブラリのソースを眺めていて、あーこうやるのかと納得した次第です。
余談
inet_atonが何なのか知らなかったのですが man inet_aton
したところ色々わかりました。
man inet_aton
...
DESCRIPTION
inet_aton() converts the Internet host address cp from the IPv4 numbers-and-dots notation into binary form (in network byte order) and stores it in the structure that inp
points to. inet_aton() returns nonzero if the address is valid, zero if not. The address supplied in cp can have one of the following forms:
a.b.c.d Each of the four numeric parts specifies a byte of the address; the bytes are assigned in left-to-right order to produce the binary address.
a.b.c Parts a and b specify the first two bytes of the binary address. Part c is interpreted as a 16-bit value that defines the rightmost two bytes of the binary
address. This notation is suitable for specifying (outmoded) Class B network addresses.
a.b Part a specifies the first byte of the binary address. Part b is interpreted as a 24-bit value that defines the rightmost three bytes of the binary address. This
notation is suitable for specifying (outmoded) Class A network addresses.
a The value a is interpreted as a 32-bit value that is stored directly into the binary address without any byte rearrangement.
...
inet_atonで変換可能なフォーマットは「192.168.1.100」のような見た目以外でも、「3232235876」とか「192.11010404」とか「192.168.356」でもいいみたいです。4オクテットのシリーズでないと正しいとみなさない、といった要件がある場合は、inet_atonに加えてそこのチェックを入れたほうがいいかも。
以下は、「192.168.1.100」と同じ変換結果になるものの変換の例です。
ipython
...
In [1]: from socket import inet_aton
In [2]: hex(192), hex(168), hex(1), hex(100)
Out[2]: ('0xc0', '0xa8', '0x1', '0x64')
In [3]: 0xc0a80164
Out[3]: 3232235876
In [4]: inet_aton("3232235876")
Out[4]: '\xc0\xa8\x01d'
In [5]: 0xa80164
Out[5]: 11010404
In [6]: inet_aton("192.11010404")
Out[6]: '\xc0\xa8\x01d'
In [7]: 0x0164
Out[7]: 356
In [8]: inet_aton("192.168.356")
Out[8]: '\xc0\xa8\x01d'