以下の内容はhttps://takuya-1st.hatenablog.jp/entry/2021/07/15/021359より取得しました。


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

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

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

計算してみる( ipaddress ) :2026/02/16 追記

python3.3 以降で 標準添付の import ipaddress を使うと楽です

import ipaddress

# ネットワークオブジェクトの作成
net = ipaddress.ip_network("209.85.128.0/17")
# IPアドレスオブジェクトの作成
ip = ipaddress.ip_address("209.85.220.73")

# 判定(in 演算子が使える!)
print(ip in net)  # => True

# ネットワークアドレスの確認
print(net.network_address)  # => 209.85.128.0

計算してみる( netaddrを使う )

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

ショートカットに

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

python3 -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='python3 -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

2026-02-16 追記 ワンライナー( ipaddress 版)も考えてみる

alias in_subnet='python3 -c "import sys, ipaddress; \
print(ipaddress.ip_address(sys.argv[1]) in ipaddress.ip_network(sys.argv[2], strict=False))"'

in_subnet 209.85.220.73 209.85.128.0/17

私としては netaddr のほうがオブジェクト指向に沿ってるので、好きだけど、pip インストールが必要なので面倒だったのが解消された

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

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

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

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 255 255 255 255
/24 255 255 255 0
/16 255 255 0 0
/8 255 0 0 0

この表は、次のようになるわけで

マスク 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オクテット(8ビット)は次のように計算されるわけで

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

オクテットを見ると、ビット数範囲が分かるわけで

マスク 1オクテット 2オクテット 3 オクテット 4オクテット
/17 8 8 1 0
/18 8 8 2 0
/19 8 8 3 0
マスク 1オクテット 2オクテット 3 オクテット 4オクテット
/17(16+1) 8 8 1 0
/18(16+2) 8 8 2 0
/19(16+3) 8 8 3 0
マスク 数値 範囲
/17(16+1) 8 8 | 1 →(0-127,128-255) | 0
/18(16+2) 8 8 | 2 →(0-63,64-127,128-191,192-256)| 0
/19(16+3) 8 8 | 3 | 0

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

マスク 数値(分割数) 範囲 数値
16+0 0 (0-255) 255
16+1 1 (0-127,128-255) 128
16+2 2 (0-63,64-127,128-191,192-255) 64
16+3 3 (0-31,32-63,...,224-255) 32

たとえば、/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

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

2026-02-16 更新

python3.3 の ipaddress に付いて言及




以上の内容はhttps://takuya-1st.hatenablog.jp/entry/2021/07/15/021359より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14