LoginSignup
1
0

プライベートIPアドレスの範囲をリアルな縮尺で示した図を作った

Posted at

プライベートIPアドレスの範囲を図で示す

IPv4では、全アドレス空間0.0.0.0~255.255.255.255のうち以下のa,b,cの範囲をプライベートIPアドレスとして使用します:

a. 10.0.0.0 ~ 10.255.255.255
b. 172.16.0.0 ~ 172.31.255.255
c. 192.168.0.0 ~ 192.168.255.255

これらの範囲を模式的に図示するとこんな感じです:
privateIP_moshiki.png
「グレーの範囲がプライベートIPの範囲です」と言われれば、そうですねと答えるしかない図ですが、しかしこの図は誇張しすぎです。グレーの範囲はもっと狭いはずです。

どういうことかというと、すべてのアドレスの数は$2^{32}$ = 4,294,967,296通り(約42億)で、実際のところ何%をプライベートIPアドレスが占めるのかを計算してみると、

a. 10.0.0.0 ~ 10.255.255.255 → $2^{24}$通りなので、$2^{24}/2^{32} \,\,\fallingdotseq \,\,0.3906\%$
b. 172.16.0.0 ~ 172.31.255.255 → $2^{20}$通りなので、$2^{20}/2^{32} \,\,\fallingdotseq \,\,0.0244\%$
c. 192.168.0.0 ~ 192.168.255.255 → $2^{16}$通りなので、$2^{16}/2^{32} \,\,\fallingdotseq \,\,0.0015\%$

a,b,cの合計でも$0.4165\%$です。少ない。

この比率をリアルに反映させたら図はどうなるの、と思い付いてしまったので作ってみました。こうなりました:
privateIP_real_monochrome.png
予想した通りスカスカになりました。満足です。a,b,cの範囲はいずれも矩形で描いてるんですが、bとcは狭すぎてほぼ線になっちゃいましたね。

需要のほどはわかりませんが使いどころがあれば図はよしなにご利用ください。カラー版も置いておきます。
privateIP_real_color.png

コード

図中の数字はパワポで書き加えましたが、中核になる図はPythonとOpenCVで作りました。

IPアドレスを数値にするところがちょっと面倒かなと思ったのですが、ipaddress --- IPv4/IPv6 操作ライブラリ というまさになライブラリがあったので使いました。こんな感じでint()をかませば数値にしてくれます。

import ipaddress
ipaddr = ipaddress.IPv4Address('192.168.0.0')
print(ipaddr) # 192.168.0.0
print(int(ipaddr)) # 3232235520

あとは、OpenCVで矩形を描くrectangle()と直線を描くline()を使って、こんな感じのコードになりました:

import cv2
import numpy as np
import ipaddress

height = 600
width = 3000
x_offset = 250
y_offset = 150
ip_box_length = width - 2 * x_offset
img = np.full((height, width, 3), (255, 255, 255), dtype=np.uint8)

IP_MAX = ipaddress.IPv4Address('255.255.255.255')
ip_head_a = ipaddress.IPv4Address('10.0.0.0')
ip_tail_a = ipaddress.IPv4Address('10.255.255.255')
ip_head_b = ipaddress.IPv4Address('172.16.0.0')
ip_tail_b = ipaddress.IPv4Address('172.31.255.255')
ip_head_c = ipaddress.IPv4Address('192.168.0.0')
ip_tail_c = ipaddress.IPv4Address('192.168.255.255')

x_head_a = x_offset + (int(ip_head_a) / int(IP_MAX)) * ip_box_length
x_tail_a = x_offset + (int(ip_tail_a) / int(IP_MAX)) * ip_box_length
x_head_b = x_offset + (int(ip_head_b) / int(IP_MAX)) * ip_box_length
x_tail_b = x_offset + (int(ip_tail_b) / int(IP_MAX)) * ip_box_length
x_head_c = x_offset + (int(ip_head_c) / int(IP_MAX)) * ip_box_length
x_tail_c = x_offset + (int(ip_tail_c) / int(IP_MAX)) * ip_box_length

cv2.rectangle(img, (x_offset, y_offset), (width-x_offset, height-y_offset), (0, 0, 0), thickness=2)
cv2.rectangle(img, (round(x_head_a), y_offset), (round(x_tail_a), height-y_offset), (0, 0, 255), thickness=-1)
cv2.rectangle(img, (round(x_head_b), y_offset), (round(x_tail_b), height-y_offset), (0, 255, 0), thickness=-1)
cv2.rectangle(img, (round(x_head_c), y_offset), (round(x_tail_c), height-y_offset), (255, 0, 0), thickness=-1)

ip_64 = ipaddress.IPv4Address('64.0.0.0')
ip_128 = ipaddress.IPv4Address('128.0.0.0')
ip_192 = ipaddress.IPv4Address('192.0.0.0')

x_64  = x_offset + (int(ip_64) / int(IP_MAX)) * ip_box_length
x_128  = x_offset + (int(ip_128) / int(IP_MAX)) * ip_box_length
x_192  = x_offset + (int(ip_192) / int(IP_MAX)) * ip_box_length

cv2.line(img, (round(x_64), y_offset), (round(x_64), height-y_offset), (128, 128, 128))
cv2.line(img, (round(x_128), y_offset), (round(x_128), height-y_offset), (128, 128, 128))
cv2.line(img, (round(x_192), y_offset), (round(x_192), height-y_offset), (128, 128, 128))

cv2.imwrite('C:\\tmp\\privateIP.png', img)
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0