CIDR プレフィックスからネットマスクを作る
CIDR プレフィックスからネットマスクを作る
このレッスンで分かること
- CIDR の
nは 0 以上 32 以下の整数です- たとえば
192.168.1.42が192.168.1.0/24に属するかは、両者を0xFFFFFF00で AND して下位 8bit を捨て、上位 24bit が一致するかを見るだけです192.168.1.0/24のような CIDR 表記は、IPv4 アドレスのうち何ビットがネットワーク部かを/nで表します
CIDR プレフィックスからネットマスク とは
/24 のような CIDR プレフィックスから、対応する 32bit のネットマスク (上位 prefix bit が 1) を返します。
192.168.1.0/24 のような CIDR 表記は、IPv4 アドレスのうち何ビットがネットワーク部かを /n で表します。今回はその n (プレフィックス長) を受け取り、対応するネットマスク (32bit 整数) を作る関数を実装します。
CIDR とは何か
以前はネットマスクを 255.255.255.0 のようにドット区切り 10 進でフル表記していましたが、現代ではすべて CIDR (Classless Inter-Domain Routing) で表記します。/24 は 上位 24bit がネットワーク部、残り 8bit がホスト部 という意味で、255.255.255.0 (= 0xFFFFFF00) に対応します。
CIDR の
nは 0 以上 32 以下の整数です。/0はすべての IPv4 (0.0.0.0)、/32は 1 つの IP だけを示します。
計算の考え方
プレフィックス n から 32bit のネットマスクを作るには、上位 n ビットを 1 にし、下位 32 - n ビットを 0 にすればよいです。これは「すべて 1 の 32bit 値」を、下位 32 - n ビット分だけ左にシフトすれば得られます。
mask = (0xFFFFFFFF << (32 - n)) & 0xFFFFFFFF
外側で & 0xFFFFFFFF を付ける理由は、n = 0 のときに (0xFFFFFFFF << 32) をすると、言語によっては未定義動作や 0 にならない結果になるからです。32bit に正規化する 保険 として AND を付けておきます。
具体例
プレフィックス n と期待されるマスクの対応表は次の通りです。
n = 0→0n = 8→0xFF000000=4278190080n = 16→0xFFFF0000=4294901760n = 24→0xFFFFFF00=4294967040n = 32→0xFFFFFFFF=4294967295
16 進数で書くと
0xFF(= 8bit が全部 1) のブロックがいくつ並んでいるかが見えやすくなります。/24ならFF.FF.FF.00、/16ならFF.FF.00.00のように。
Python 実装
Python
def cidrMask(n):
if n <= 0:
return 0
if n >= 32:
return 0xFFFFFFFF
return ((0xFFFFFFFF << (32 - n)) & 0xFFFFFFFF)Python の int は任意精度なので、<< 32 はオーバーフローしませんが、安全のため n = 0 と n = 32 を 早期 return で分岐しています。
JavaScript 実装
JavaScript
function cidrMask(n) {
if (n <= 0) return 0;
if (n >= 32) return 4294967295;
return (Math.pow(2, 32) - Math.pow(2, 32 - n));
}JavaScript ではビットシフトが 32bit 符号付きで挙動が読みづらいので、累乗 を使って書きました。2^32 - 2^(32-n) は「上位 n bit だけが 1 の値」と同値です。たとえば n = 24 なら 2^32 - 2^8 = 4294967296 - 256 = 4294967040 です。
累乗で書くと 32bit 符号の罠を回避できます。
Math.pow(2, 32) - 1が0xFFFFFFFFの値です。
なぜマスクが大切なのか
IP アドレス ip がサブネット net/n に属するかを判定するには、次のように bit AND を取って比較します。
(ip & mask) == (net & mask)
たとえば 192.168.1.42 が 192.168.1.0/24 に属するかは、両者を 0xFFFFFF00 で AND して下位 8bit を捨て、上位 24bit が一致するかを見るだけです。ルーティングテーブルの 最長一致 もこの仕組みで O(プレフィックス長) で実装できます。
よくある間違い
nと32 - nを取り違える (向きが逆になる)0xFFFFFFFF << 32を呼び出してしまい、言語によって結果が0xFFFFFFFFのままだったり0だったり未定義だったりする- JavaScript で
<<を使うと負の数になるケースを忘れる nの範囲チェック (0 〜 32) を省き、/40のような不正値で 巨大な数 が返る- ネットワーク部とホスト部を逆向きに作り、下位 n bit が 1 のマスクになる
やってみよう
関数 cidrMask(n) を実装してください。n は 0 以上 32 以下の整数で、対応する 32bit ネットマスク (上位 n bit が 1) の整数を返します。n = 0 のときは 0、n = 32 のときは 4294967295 を返します。
よくある質問
Q. このトピックを覚える意味は何ですか?
A. CIDR表記はIPアドレスの世界の共通言語です。サブネット設計、ファイアウォールルール、クラウドのVPC設定など、ネットワークに関わる作業をするなら避けて通れません。ビット演算でネットマスクを作れるようになると、「なぜこのIPはこのサブネットに属するのか」を暗算で判断できるようになります。
Q. 実務でこの知識を使う場面は?
A. AWS VPCやセキュリティグループのCIDR範囲設定、社内ネットワークのサブネット分割設計、アクセス制御リスト(ACL)でのIP範囲指定など、インフラ構築・運用のあらゆる場面で登場します。
Q. 他の章とどう繋がりますか?
A. 前の章で扱ったビット演算(AND, シフト)がそのまま計算の核になります。次の単純チェックサムのレッスンでも、32bit整数をビット単位で操作する視点を引き続き使います。
次のレッスン
次は 単純チェックサム に進みましょう。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- CIDR マスク の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. CIDR マスク とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- 上位 n bit が 1、下位 (32 - n) bit が 0 の 32bit 整数を返す
- n=0 のとき 0、n=32 のとき 4294967295 を返す
- n の範囲は 0 から 32
入出力例
test-cases.txt
cidrMask(0) → 0
cidrMask(8) → 4278190080
cidrMask(16) → 4294901760
cidrMask(24) → 4294967040
cidrMask(32) → 4294967295
cidrMask(1) → 2147483648
cidrMask(4) → 4026531840
cidrMask(28) → 4294967280