Help us understand the problem. What is going on with this article?

PythonでIPアドレスの文字列表現が正しいフォーマットか確認する

More than 1 year has passed since last update.

はじめに

タイトルのとおり、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'
triplew
世界中の人々が健康で尊厳ある日々を送れる社会を創造します。
http://dfree.biz/aboutus/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away