PythonでIPアドレス(IPv4/IPv6)を検証する方法
はじめに
文字列が与えられたとき、それが有効なIPv4アドレスか、有効なIPv6アドレスか、あるいはどちらでもないかを判定する方法を解説します。
IPv4アドレスのルール
IPv4アドレスは、ドット区切りの10進表記(ドット・デシマル記法)で表されます。これは0から255までの範囲にある10進数4つをドット(".")で区切った形式で、例えば「192.168.254.1」のようなものです。
なお、先頭に余分なゼロが付いたIPv4アドレスは無効とみなされます。たとえば「192.168.254.01」は不正なアドレスです。
IPv6アドレスのルール
IPv6アドレスは、16ビットを表す4桁の16進数8グループで構成され、各グループはコロン(":")で区切られます。例えば「2001:0db8:85a3:0000:0000:8a2e:0370:7334」は有効なアドレスです。
また、各グループ内の先頭のゼロは省略でき、英字の大文字・小文字も区別されないため、「2001:db8:85a3:0:0:8A2E:0370:7334」も有効なアドレスとして扱われます。
ただし、この判定では簡略化のために連続するゼロのグループを「::」(連続したコロン)で置き換えることは許されません。そのため「2001:0db8:85a3::8A2E:0370:7334」は無効なIPv6アドレスとなります。さらに、IPv6では過剰な先頭ゼロも無効であり、「02001:0db8:85a3:0000:0000:8a2e:0370:7334」のようなアドレスは不正です。
解決の手順
この問題は以下の手順で解くことができます。
- メソッド checkv4(x) を定義します。xが0〜255の範囲内であればtrue、そうでなければfalseを返します。
- メソッド checkv6(x) を定義します。動作は以下の通りです。
- xの長さが4より大きい場合はfalseを返す
- xの10進数値が0以上で、かつ先頭文字が"-"でなければtrue、それ以外はfalseを返す
- メインメソッドでは次のように判定します。
- 入力にドットが3つ含まれ、すべての部分でcheckv4(i)がtrueなら「IPv4」を返す
- 入力にコロンが7つ含まれ、すべての部分でcheckv6(i)がtrueなら「IPv6」を返す
Pythonでの実装例
以下の実装を見ると、処理の流れがより理解しやすくなります。
class Solution(object):
def validIPAddress(self, IP):
"""
:type IP: str
:rtype: str
"""
def isIPv4(s):
try: return str(int(s)) == s and 0 <= int(s) <= 255
except: return False
def isIPv6(s):
if len(s) > 4:
return False
try : return int(s, 16) >= 0 and s[0] != '-'
except:
return False
if IP.count(".") == 3 and all(isIPv4(i) for i in IP.split(".")):
return "IPv4"
if IP.count(":") == 7 and all(isIPv6(i) for i in IP.split(":")):
return "IPv6"
return "Neither"
ob = Solution()
print(ob.validIPAddress("172.16.254.1"))
コードのポイント
str(int(s)) == s:文字列を一度整数に変換して再び文字列化し、元の文字列と一致するかを確認することで、先頭ゼロの有効性をチェックできます。int(s, 16):文字列を16進数として解析します。不正な文字が含まれていれば例外が発生します。try / except:変換できない入力に対してはFalseを返すことで、プログラムがエラーで停止しないようにしています。
入力
"172.16.254.1"
出力
"IPv4"
-
PythonでIPアドレスを無害化(Defang)する方法
IPアドレスの無害化(Defang)とは有効なIPv4アドレスが与えられたとき、その「無害化(Defang)バージョン」を返すことを考えます。無害化されたIPアドレスとは、すべてのピリオド「.」を「[.]」に置き換えたものです。例えば、IPアドレスが「192.168.4.1」であれば、出力は「192[.]168[.]4[.]1」となります。この処理は、セキュリティの分野でよく使われます。記事やログの中に実際のIPアドレスがそのまま記載されると、自動化されたクローラーやマルウェアがそれを本物のアドレスとして認識してしまう恐れがあるためです。「[.]」という表記にすることで、人間には読みやすく、機
-
Pythonで関数から複数の値を返す5つの方法【タプル・辞書・クラス・リスト・ジェネレータ】
Pythonの関数は、複数の値を一度に返すことができます。返された値はそのまま変数に格納でき、関数が返せるのは1つの変数だけとは限りません。0個、1個、2個、それ以上の値でも自由に返せます。実は、この「複数の値を返せる」という性質はPythonの標準的な機能です。C++やJavaなど、多くの他のプログラミング言語では利用できない便利な特徴といえます。関数から複数の値を返すには、目的に応じてタプル、リスト、辞書などのオブジェクトを活用します。本記事では、代表的な5つの方法をコード例とともにわかりやすく解説します。方法1:タプル(tuple)を使うdef func(x): y0 = x +