IPアドレスをセグメント記述と数値記述に相互変換する方法
1.概要
IPアドレスはドットで区切られたIPv4アドレスが良く知られています。しかし、内部処理ではドットで区切られたIPv4アドレスを数値IPv4アドレスに変換されて利用されていることもあります。ドットで区切られた一般的なIPv4アドレスと数値IPv4アドレスの変換について、簡単な処理を作成したので、その内容を記述します。
2.詳細
(1) 一般的なIPv4アドレスと数値IPv4アドレスの相互変換(shell版)
IPアドレスの配布はセグメント単位です。IPアドレスがIPアドレスセグメントに含まれているかを調べる必要がありますが、IPv4のIPアドレスはドットで分割されたアドレスです。例えば、192.168.10.1などです。しかし、この表記の場合、あるIPアドレスがIPアドレスの範囲(192.168.9.0 - 192.168.10.255)に含まれていることを調べるには不便です。そこで、IPアドレスを10進数に変換してから調べます。
192.168.9.0 => 3232237824
192.168.10.1 => 3232238081
192.168.10.255 => 3232238335
上記結果から数値化することで、大小比較が容易できます。そこで、IPアドレスを10進数に変換する処理をshellで作成しました。今回はその内容を記述します。
作成したshell
(a) ipから10進数(ip2dec.sh)
#!/bin/bash
ip2dec(){
echo $(($1 * 16777216 + $2 * 65536 + $3 * 256 + $4))
}
IP1=$(echo $1 | tr "." " ")
ip2dec $IP1
(b) 10進数からip(dec2ip.sh)
#!/bin/bash
dec2ip(){
a=$(($1 / 16777216))
x=$(($a * 16777216))
b=$((($1 - $x) / 65536 ))
y=$(($b * 65536))
c=$((($1 - $x - $y) / 256))
z=$(($c * 256))
d=$(($1 - $x - $y - $z))
echo "$a.$b.$c.$d"
}
dec2ip $1
利用方法
上記shellをip2dec.shとdec2ip.shで作成したとします。
sh ip2dec.sh 192.168.10.1
3232238081
sh dec2ip.sh 3232238081
192.168.10.1
となります。
参考資料では、a * 256 ** 3 + b * 256 ** 2 + c * 256 + d
の計算式を利用していますが、私の環境ではエラーとなりました。
そこで、下記計算をした上でshellを作成しました。
256 ** 3 = 16777216
256 ** 2 = 65536
これでエラーはなくなりました。
(2) 一般的なIPv4アドレスと数値IPv4アドレスの相互変換(python版)
前回、shellを利用してIPアドレスを変換する処理を記述しました。しかし、国レベルに配布されているIPアドレスセグメントを変換するにはshellでは処理に時間を必要とします。
そこで、bash shellで記述した処理をpython3で書き直しました。本ブログのIP address convert using shellを参照してください。大量に変換処理をすると、bash shellよりもpython3の方が非常に高速です。今回は、この内容を記述します。
作成したapp(ipconvert.py)
def ip2dec(ip):
ip = ip.split(".")
result = 0
for i in range(0,4):
result = int(ip[i]) * 256 ** (3 - i) + result
return result
def dec2ip(dec):
result = ""
for i in range(0,4):
item = dec // 256 ** (3 - i)
result = result + str(item)
if i != 3:
result = result + "."
dec = dec - item * 256 ** (3 - i)
return result
if __name__ == "__main__":
print(ip2dec("192.168.10.1"))
print(dec2ip(3232238081))
実行方法
python3 ipconvert.py
3232238081
192.168.10.1
(3) IPv4アドレス範囲をサブネット方式からネットマスク方式へ変換(python版)
IP addressの範囲指定方法は、192.168.0.0/24などのセグメント記述方法と192.168.0.0-192.168.0.255とIPアドレスの範囲を指定する方法があります。今回は、セグメント記述方法をアドレス範囲記述方法へpython3のプログラムで変換します。
以下のような変換ができることを目標にします。
"192.168.0.0/24" => ['192.168.0.0','192.168.0.255']
"172.16.0.0/16" => ['172.16.0.0','172.16.255.255']
"10.0.0.0/8" => ['10.0.0.0','10.255.255.255']
python3の関数(ipseg.py)
def seg2rng(segment):
seg = segment.split("/")
ips = seg[0].split(".")
ipe = seg[0].split(".")
mask = int(seg[1])
wk0 = mask//8
wk1 = 2 ** ((wk0 + 1) * 8 - mask) - 1
wk2 = int(ips[wk0]) + wk1
ipe[wk0] = str(wk2)
for i in range(3,wk0,-1):
ipe[i] = "255"
return ['.'.join(ips),'.'.join(ipe)]
if __name__ == "__main__":
print(seg2rng("192.168.0.0/24"))
実行方法
python3 ipseg.py
['192.168.0.0', '192.168.0.255']
(4)国別に配布されたIPアドレスの調べ方
セキュリティが話題となる中で、フィルタリングされたIPアドレスを調べたいと思うことがあります。whoisやcmanを利用することで調べることができるIPアドレスがありますが、調査が難しい場合もあります。国単位に配布されたIPアドレスは公開されているので、どこの国のIPアドレスであるかを調べることはできます。
IPアドレスがどの国に割り当てられているかを調べるためには、まず、各国のドメイン名を調べて、次に、その国に割り当てられたIPアドレスセグメントを調べます。PythonによるIP変換処理のプログラムルーチンができているので、調査方法を記載します。
JPNICのドメイン名の種類でccTLDを調べます。日本はjpですね。次に、jpに割り当てられているIPセグメントをfetusで調べます。これで必要な情報を収集できたので、処理を記述するだけになります。今回は手順のみを記述します。
本ブログのIPアドレス変換処理のcodeを参照の上、活用してください。
日本に割り当てられているIPアドレスセグメント表記をIPアドレス範囲表記に修正後、数値形式にします。
(a) 日本に割り当てられたIPセグメント一覧を入手します
(b) セグメント記述(1.0.16.0/20)をIPアドレス範囲に修正します。
(c) IPアドレスを数値形式に変換します。
(d) 不明なIPを数値形式に変換後、日本に割り当てられたIPか否かを調べることが容易にできます。
調査するIPが大量となる場合は、照合処理が必要ですが、プログラム作成が必要です。
3.所見
shell版の ipから10進数(ip2dec.sh)は簡潔に記述できたと思っています。この記述方式が見つかったのでこの記事を作成することになりました。IPv4の枯渇でIPv6にシフトしていますが、プライベートアドレスを利用することで当面の間はIPv4を利用すると考えています。
参考
[本ブログ内参照]・LinutMintでPDFからTextを作成する方法
コメント
コメントを投稿