コンピューターサイエンス入門:理論編
IPv4 アドレスを 32bit 整数に変換
この回でやること
IPv4の4つの数に掛かる重みを読み解き、符号なし整数への対応を確かめます。
- 読む 約 7 分
- 最後にクイズ 1 問
アクセス元のIPを並べ替えたら、9.0.0.0 が 10.0.0.0 より後ろに来た。文字列のまま比べると辞書順になるので、こういうことが起きます。IPを数として扱えば、比較や範囲の判定に使えます。
文字列の順と数の順は違う
文字列の比較は先頭から文字を比べます。「10」は「9」より前に来ても、数の10は9より大きいですよね。点で区切ったIPv4の表記は、人が読むための形です。中身の32ビットを符号なし整数として読めば、数としての順に並べられます。
ログ集計やIPの遮断範囲を比べる場面で役立ちます。DBには0から4,294,967,295まで入る型が必要です。符号付き32ビットでは上半分が入りません。
4つの数に別々の重みを掛ける
点で区切った4つの数は、それぞれ0から255で、8ビットに収まります。これをオクテットと呼びます。左から24、16、8、0ビットの位置に置くので、対応する重みは次のようになります。
| 位置 | 重み |
|---|---|
| いちばん左 | 256の3乗 = 16,777,216 |
| 左から2つ目 | 256の2乗 = 65,536 |
| 左から3つ目 | 256 |
| いちばん右 | 1 |
各オクテットに重みを掛け、足し合わせます。1つ左へ移ると256倍になる、256進数のような読み方です。ビットを左へずらす操作でも同じ配置になります。8ビットずつの範囲が重ならないため、加算でもORでもまとめられます。
同じ形は色にも使われます。赤、緑、青をそれぞれ8ビットで並べる例です。
Python
r, g, b = 0x33, 0xAA, 0x66
color = (r << 16) | (g << 8) | b
print(hex(color)) # 0x33aa660x は16進数、<< は左へずらす印です。位置を間違えると別の色になります。
JavaScriptでは符号に注意する
JavaScriptのビット演算は、原則として符号付き32ビットで計算します。先頭のオクテットが128以上だと最上位ビットが1になり、組み合わせた結果が負になることがあります。
例題で確かめる
10.2.3.4 を整数として読みます。各部分は0から255に収まっています。
プレーンテキスト
10 × 16,777,216 = 167,772,160
2 × 65,536 = 131,072
3 × 256 = 768
4 × 1 = 4
合計 = 167,904,0044つを足した19でも、点を消した10234でもありません。位置ごとの重みが、元の4つの数を区別します。