IPアドレス変換(10進数・16進数・2進数)
IPアドレスを10進数・16進数・2進数・8進数に変換し、これらの数値を入力すればIPアドレスに戻します。各オクテットを8ビットとその重みで図示するので、計算の過程を追うことができます。
読み取った形式: ドット付き10進表記
| オクテット | 1286432168421 | 16進数 |
|---|---|---|
| 198 | 11000110 | C6 |
| 128+64+4+2 × 256³ = 3,321,888,768 | ||
| 51 | 00110011 | 33 |
| 32+16+2+1 × 256² = 3,342,336 | ||
| 100 | 01100100 | 64 |
| 64+32+4 × 256 = 25,600 | ||
| 77 | 01001101 | 4D |
| 64+8+4+1 × 1 = 77 | ||
| 合計 | ||
| = 3,325,256,781 | ||
IPアドレスを入力するか、その10進数・16進数・2進数・8進数の数値を入力してIPアドレスに戻します。変換はブラウザー内で行い、何も送信しません。
3325256781
同じ数値をコードで
SELECT INET_ATON('198.51.100.77');3325256781SELECT '198.51.100.77'::inet - '0.0.0.0'::inet;3325256781int(ipaddress.ip_address('198.51.100.77'))3325256781ip2long('198.51.100.77')3325256781- ドット付き10進表記
- 10進数
- 16進数
- 2進数(オクテットごと)
- 8進数
- 16進数(オクテットごと)
- 8進数(オクテットごと)
- ブラウザーで(どれも198.51.100.77を開きます)
- 逆引きDNS名
- IPv6表記(IPv4射影)
- IPv4 → IPv6
IPアドレスを10進数に変換する方法は?
4つの数にそれぞれ256³、256²、256、1を掛けて合計します:192.168.1.1は192 × 16,777,216 + 168 × 65,536 + 1 × 256 + 1 = 3,232,235,777です。
IPv4アドレスは、8ビットずつ4つに分けて書いた1つの32ビットの数値なので、ドット付きの形と10進数の形は同じ値です。MySQLのドキュメントでは、例として10.0.5.9 = 167773449を挙げています。

どの形式でも入力ドット付き10進表記、10進数、16進数、2進数、8進数、URL:入力欄はどれも読み取ります。ビットと重み1のビットがそれぞれの重みを加えます:128 + 64 + 4 + 2 = 198。× 256³、256²、256、1各オクテットにその重みを掛け、最後に合計します。すべての形式で出力16進数、2進数、8進数、ブラウザーが受け付けるURL。それぞれコピーできます。数値アドレス全体を1つの32ビットの数値で表示します。コピーでき、アドレスの種類も示します。10進数をIPアドレスに変換する方法は?
16,777,216で割り、その余りを65,536で、さらにその余りを256で割ります:3つの商と最後の余りが4つの数になるので、3232235777は192.168.1.1です。
変換ツールに数値を入力すると同じ計算を行い、16進数、2進数、8進数、ブラウザーが受け付ける形式もあわせて表示します。4,294,967,295より大きい数はIPv4アドレスではありません。変換ツールはそれをIPv6の数値として読み、そのことを表示します。
3,232,235,777÷ 16,777,216=192余り 11,010,30511,010,305÷ 65,536=168余り 257257÷ 256=1余り 11÷ 1=1余り 0192.168.1.1
IPアドレスを2進数に変換する方法は?
4つの数をそれぞれ、重み128、64、32、16、8、4、2、1の8ビットで書きます:192は128 + 64なので11000000、192.168.1.1は11000000.10101000.00000001.00000001です。
重みを左から順に見ていき、その値が残りに収まれば1を書いて引き、収まらなければ0を書きます。168の場合:128は収まる(残り40)、64は収まらない、32は収まる(残り8)、16は収まらない、8は収まる、なので10101000です。2進数から戻すには、1のビットの重みを足します。
| 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | ||
|---|---|---|---|---|---|---|---|---|---|
| 192 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 128 + 64 |
| 168 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 128 + 32 + 8 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
11000000.
IPアドレスを16進数に変換する方法は?
各オクテットの8ビットを4ビットずつ2つに分け、それぞれを16進数1桁で書きます:192は1100 0000、つまりC0なので、192.168.1.1は0xC0A80101です。
16進数は、IPv6が埋め込みのIPv4アドレスを書くときの形でもあります:::ffff:c0a8:101は192.168.1.1です。ブラウザーは16進数の数値をホストとして受け付けるので、http://0xC0A80101/は192.168.1.1を開きます。
11000000C010101000A8000000010100000001010xC0A80101
4ビット = 16進数1桁
http://3232235777で192.168.1.1が開くのはなぜ?
ブラウザーは、数字だけでできたホストを、昔のinet_atonが受け付けるいずれかの形式(10進数1つだけの形も含む)のIPv4アドレスとして読み、ドット付きのアドレスを読み込むからです。
各部分は10進数(URL Standard)、0x付きの16進数、先頭が0の8進数のいずれでもよく、部分が4つより少なければ最後の部分が残りのバイトを埋めます。そのためhttp://192.168.1/は192.168.1.1ではなく192.168.0.1を開きます。pingとcurlも同じ形式を受け付けます。
32ビットを超える数、0で始まる部分に含まれる8や9、5つ目の部分は拒否されます。
| アドレスバーに入力 | 開く先 |
|---|---|
http://3232235777/ | 192.168.1.1 |
http://0xC0A80101/ | 192.168.1.1 |
http://0300.0250.1.1/ | 192.168.1.1 |
http://127.1/ | 127.0.0.1 |
http://192.168.1/ | 192.168.0.1 |
http://4294967296/ | 拒否 |
http://09/ | 拒否 |
http://192.0.2.1.5/ | 拒否 |
IPアドレスの別表記がセキュリティ上問題になるのはなぜ?
アドレスを文字列として比較するフィルターはだまされることがあるからです:2130706433、0x7f.1、127.1、::ffff:127.0.0.1はすべて127.0.0.1なので、フィルターは文字列ではなく数値として比較しなければなりません。
OWASPは、こうしたエンコーディングをSSRF対策を回避する手口の1つに挙げています。実際にこのバグを出荷したライブラリもあります:npmのnetmaskとipパッケージ、Pythonのipaddress、Goのnetパッケージはいずれも、ある時点で先頭のゼロや別表記を誤って読んでおり、その後修正されています。
厳格なパーサーで解析し、数値に変換してから範囲を比較してください。ブロック対象の範囲のIPv4射影アドレスもブロックしてください。
deny 127.0.0.1
文字列として比較
127.0.0.1ブロック
2130706433すり抜ける
0x7f.1すり抜ける
127.1すり抜ける
::ffff:127.0.0.1すり抜ける
数値として比較
127.0.0.12130706433 · ブロック
21307064332130706433 · ブロック
0x7f.12130706433 · ブロック
127.12130706433 · ブロック
::ffff:127.0.0.12130706433 · ブロック
IPv6アドレスを10進数に変換する方法は?
16ビットのグループ8つで同じように計算します:2001:db8::1は42540766411282592856903984951653826561で、最大39桁になる数値なので、JavaScriptではBigIntが必要です。
IPv6アドレスは2^128個あります。JavaScriptの数値が整数を正確に保持できるのは2^53 − 1までなので、通常の計算ではIPv6の値が気付かないうちに丸められます。Pythonのint(ipaddress.ip_address(…))は正確です。
2001:db8::1
42540766411282592856903984951653826561
正確(BigInt)
42540766411282592856903984951653826560
Number():2^53を超えると丸められる
コードやデータベースでIPアドレスを数値に変換するには?
各プラットフォームの関数を符号なしの型と組み合わせて使います:MySQLのINET_ATON()とINT UNSIGNED、PostgreSQLのinetの引き算、Pythonのint(ipaddress.ip_address(…))、JavaScriptではシフトの後に>>> 0です。
符号付き32ビット整数では128.0.0.0以上のアドレスを保持できません:JavaScriptの<<は192.168.1.1に対して-1062731519を返し、PHPのip2long()は32ビットのビルドで負の値になります。IPv6には、MySQLではINET6_ATON()とVARBINARY(16)を使います。
› SELECT INET_ATON('192.168.1.1'), INET_NTOA(3232235777); 3232235777 | 192.168.1.1
MySQL 8.4
› SELECT '192.168.1.1'::inet - '0.0.0.0'::inet, '0.0.0.0'::inet + 3232235777; 3232235777 | 192.168.1.1
PostgreSQL 16
› import ipaddress int(ipaddress.ip_address('192.168.1.1')), ipaddress.IPv4Address(3232235777) (3232235777, IPv4Address('192.168.1.1'))
Python ipaddress
› '192.168.1.1'.split('.').reduce((n, o) => (n << 8) | +o, 0) >>> 0 3232235777
JavaScript
› echo ip2long('192.168.1.1'), ' ', long2ip(3232235777); 3232235777 192.168.1.1
PHP 8
よくある質問
192.168.1.1を10進数にすると?
IPv4アドレスの10進数の最大値は?
3232235777をIPアドレスに戻すには?
IPアドレスの010のような先頭のゼロは何を意味しますか?
192.168.1で192.168.0.1が開くのはなぜですか?
IPアドレスを手計算で2進数に変換するには?
MySQLでIPアドレスを数値として保存するには?
JavaScriptやPHPでIPの数値が負になるのはなぜですか?
IPv6アドレスは10進数に変換できますか?
http://0x7f000001/は127.0.0.1と同じですか?
足りないものはありますか?機能や新しいツールを提案する
関連ツール
IPv6からIPv4変換
IPv6に含まれるIPv4を抽出:射影・NAT64・6to4・Teredo・ISATAPをビット単位で
IPv4からIPv6変換
IPv4アドレスのすべてのIPv6形式:射影・NAT64・6to4、使用中か、まれかも表示
IPv6省略・展開
RFC 5952の方法でIPv6アドレスを省略・展開し、各ゼロを消した規則も表示
自分のIPアドレス確認
パブリックIPのIPv4とIPv6を同時に表示。ネットワーク、位置情報、VPNチェック付き
IPv6接続確認テスト
IPv6が使えるか、ブラウザーがどちらを選ぶか、サイトのIPv6対応を確認
サブネット計算機
IPv4・IPv6ブロックのネットワーク、ブロードキャスト、使用可能なホスト、マスクを計算。VLSM、分割、クラウドのサブネットにも対応
逆引きDNS
PTRレコードでIPアドレスに関連するホスト名を検索
DNS検索
ドメイン自身のネームサーバーから全DNSレコードを取得し、GoogleとCloudflareのキャッシュと比較