それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

IPアドレスが、サブネットに含まれるか判定する( python )

python で ip address がネットワークに含まれるか計算したい

このIP 209.85.220.73 この、ネットワーク 209.85.128.0/17 に入るんだっけ。

計算してみる

python の netaddr パッケージを用いて計算する

pip install netaddr
##または pipenv 経由で
pipenv run pip install netaddr

要は、ふたつのIPのネットワークアドレスが一致すればいいわけですからこうすればいい。

from netaddr import * 

a = IPNetwork("209.85.220.73/17")
a.network # => IPAddress('209.85.128.0')
b = IPNetwork("209.85.128.0/17")
b.network # => IPAddress('209.85.128.0')
a.network ==  b.network

ショートカットに

これ、もうワンライナーで動きそうですね。

python -c "import sys;from netaddr import *; \
 
print( \
 IPNetwork(sys.argv[1]).network
  ==  IPNetwork(sys.argv[2]).network) \
" 209.85.220.73/17 209.85.128.0/17

だったら alias でいけるか。

alias in_subnet='python -c "import sys;from netaddr import *; print(IPNetwork(sys.argv[1]).network ==  IPNetwork(sys.argv[2]).network)" '

in_subnet 209.85.220.73/17 209.85.128.0/17

サブネットの計算は暗算できたほうが嬉しい

サブネットが一致するかの計算って、だいたいパターンなので暗算できるんだけど。

たとえば次のようにする。

209.85.220.73/17 を計算するに、

209.85.220.73/17 → 16+1 
209.85.0.0/16 + 220/1 + 0
209.85.0.0/16 + 128 + 0
209.85.0.0/16 + 0.0.128.0 + 0.0.0.0
だから
209.85.220.73/17 → 209.85.128.0/17

範囲もそこから想像がつく

209.85.128.0/17  →  209.85.128.0 ~ 209.85.255.255

なので、209.85.220.73は範囲に含まれる。

これは、つぎの表を丸暗記しておけば、サクッと計算できるわけで。

マスク 1オクテット 2オクテット 3 オクテット 4オクテット
/32 8 8 8 8
/24 8 8 8 0
/16 8 8 0 0
/8 8 0 0 0

IPアドレスのオクテット

1 2 3 4 5 6 7 8
7 6 5 4 3 2 1 0
128 64 32 16 8 4 2 1

これを覚えておけば、だいたい計算できるわ

たとえば、/26の場合

26=24+2 なので、24 までの /255.255.255.0 までは変換しないとわかる。残りの2相当つまり、 0.0.0.64 の足し算だとわかる。

たとえば、 /17 の場合

17 の場合は、16+1 なので、16までの /255.255.0.0 は変換しないとわかる。残りの1相当つまり、 128 が以降がネットワークアドレスとわかる。

209.85.128.0/17 の場合

209.85.128.0/17 
→ 209.85.128.0/16+1
→ 209.85.0.0/16 + 0.0.128.0
→ 209.85.128.0

209.85.220.73/17の場合

209.85.220.73/17
→ 209.85.220.73/(16+1)
→ 209.85.0.0/16 + 0.0.220.73/17
→ 209.85.0.0/16 + 0.0.128.0
→ 209.85.128.0

はたして、暗算での判断と、計算機を用いた場合のどちらが速いんだろう。