IPアドレスの不思議な表記

ふだん何気なく使っている IPアドレス(IPv4アドレス)の表記ですが、実は考えてみると表現としてちょっと不思議な書き方をします。

後述するように IPアドレスの書き方は何パターンも考えられるのですが、実際に世の中で IPアドレスを書くときは、99.9%以上、次のような書き方をしていると思います。

192.168.3.1

ドットで区切られた 4つの数字が並びます。各数字は最大3ケタに見えますが、実はもっと制約があって 0~255 の範囲しか使いません。

0~255 という変な範囲の正体は、16進数表現の2ケタを 10進数に変換したもの、だからです。

16進数表現の 2ケタ、という言葉の意味がわからないと思いますが、10進数表現の 2ケタ、ならどうでしょうか。

10進数の 1ケタは、0~9 です。同様に 2ケタ(上位が 0 の場合も含む)は 0(00)~99 です。

16進数では 10進数の 9までの数字だけでは種類が足りないのでアルファベットを借りて、(10進数の)10 から 15 を、A から F で表します。10進数と紛らわしいので、16進数の数字を書くときは先頭に x を付けます。

16進数の 1ケタは x0~xF です。10進数で表現すると、0~15 になります。同様に 2ケタは x0(x00)~xFF になります。これを 10進数で表現したのが、0~255 の正体です。

なぜこんな変換が行われているのでしょうか。

実はもっと元を言えば IPアドレスは 10進数で書かれているわけでも、16進数で書かれているわけではありません。コンピュータ(やルータ)内部の物理的な電気信号に一番近い表現は 2進数です。2進数を数字で書くときは先頭に b を付けます。

2進数の 1ケタは b0~b1 です。10進数で表現すると、0~1ですね。2ケタは b0(b00)~b11 です。これは 10進数で表現すると 0~3 です。IPアドレスで出てきた 10進数の 0~255 = 16進数の x0~xFF を 2進数で表現するとどうなるでしょうか。正解は、b0~b11111111 です。8ケタです。ケタが多くて、目がチカチカしてきます。

IPアドレスは 32bit の大きさを持っています。bit はすなわち 2進数ですので、32bit の数字は 32ケタで表します。つまり、b0~b111111111111111111111111 です。これはさすがに人間が読むのは困難です。

32ケタの 2進数を、10進数で書いてみてはどうでしょう。最初の例で出した、192.168.3.1(IPアドレス表現)を、2進数で書くと、b11000000101010000000001100000001 になります。これを 10進数で表現すれば、3,232,236,289 なんですがケタが多すぎてよくわかりません。32億3千2百2十3万6千2百8十9。ちなみに 16進数だと xC0A80301 です。短くはなりましたがよみづらいです。

そこで、32ケタだった IPアドレスを 8ケタずつ、4つに区切りを入れて表現します。2進数だと b11000000 . b10101000 . b00000011 . b00000001 です。区切りを入れるだけでだいぶ読みやすさが出てきてる感じがあります。表現してる内容は変わっていません。

これを同じように区切ったまま 16進数で書いてみます。xC0 . xA8 . x03 . x01 だいぶスッキリしました。個人的にはこの表記でわかりやすくて良いと思うのですが、IPアドレスをこんな風に書く人は私以外知りません。

そこでもう一歩。同じ区切りの数字を 10進数で書くと、192.168.003.001 = 192.168.3.1、そう見慣れたあの IPアドレスのスタイルになっています。

つまり、IPアドレスの表記というのは、ケタが大きすぎてパッと見て把握しづらいのを、人間が処理しやすいように 4つで分割した上で、さらにもうひと工夫加えて、使い慣れない 2進数や 16進数が現れないように表記しただけです。区切りにはなんの意味もありません。

いやいや、ちょっとまてよ、と。IP にちょっと詳しい人だと思うかもしれません。そこの区切りをオクテッドと呼んで、4つのうち上から 3つが共通だと同じネットワーク、違えば違うネットワークになってるから意味はあるんじゃないかと。

この指摘、ある意味では当たっていますが、厳密に言えばただの思いこみです。

実は最初の例で書いた IPアドレスは完全な表現ではありません。IPアドレスを表すときは、その IPアドレスが参加するネットワークを表す必要があります。ネットワークの表し方にもいくつかの方法あるのですが、よく使われるのがサブネットを使う表記です。

こちらは IPアドレスの表記と違って、流派があります。と言っても、2通りです。

一つが、

192.168.3.0/24

のように、ネットワークアドレス(幅のあるネットワークの中の一番、数字が小さい = 先頭のアドレス)とサブネットのマスク値をスラッシュのあとに 10進数で書く方法です。

もうひとつが、

192.168.3.0 netmask 255.255.255.0

のように、ネットマスクも IPアドレス的に 4つに分割して 10進数で書く方法です。だいぶ違って見えますが、両者は同じことを表現しています。

後者の書き方、IPアドレス的表現の 255.255.255.0 を 2進数に変換してみましょう。b11111111 . b11111111 . b11111111 . b00000000 です。ケタは多いものの、なにかきれいな並びになりました。区切りを無視して、先頭から 1が何ケタ続いているか数えてみます。全体で 32ケタのうち、24ケタが b1 になっていると思います。

これがネットマスクの最初の表現、/24 の数字の意味です。

ネットマスクは IPアドレスと違って、2進数表現したときに b1b0 が交互に現れることはありません。必ず、先頭から何ケタかの b1 が続き、残りは b0 になります。そこで、先頭から続くケタ数だけを書く、というズルをしたのが /24 というネットマスクの書き方です。

192.168.3.0/24 のネットワークには、192.168.3.0 から 192.168.3.255 までの、256個の IPアドレスがあります。たしかに、区切ったときに先頭から 3 つめまでは同じになっています。

では、ネットマスクが変わって、/22 だったらどうでしょうか。

IPアドレスの 192.168.3.1 が属するネットワークのネットマスクが /22 なら、

192.168.0.0/22
=
192.168.0.0 netmask 255.255.252.0

になります。このネットワークには、192.168.0.0 から 192.168.3.255 までの、1,024個の IPアドレスがあります。すべて同じネットワークに属しています。区切ったとき、先頭から 2ケタは同じですが、3ケタ目は 0、1、2、3 の 4通りが出てきます。つまり、4つに区切ったときの数字を見るだけではネットワークが同じかまでは判断できません。

今度はネットマスクが /29 だったらどうでしょうか。

IPアドレスの 192.168.3.1 が属するネットワークのネットマスクが /29 なら、

192.168.3.0/29
=
192.168.3.0 netmask 255.255.255.248

になります。このネットワークには、192.168.3.0 から 192.168.3.7 までの、8個の IPアドレスがあります。お隣のネットワーク、

192.168.3.8/29
=
192.168.3.8 netmask 255.255.255.248

には、192.168.3.8 から 192.168.3.15 まであります。区切ったときの先頭から 3つめまではおなじになっていますが、これは  192.168.3.1 が属する 192.168.3.0/29 とは違うネットワークです。

やはり、数字を見ただけでネットワークが同じかはわかりません。

たまたま(=偶然)よく使われる /24 のネットワークだと 4つに区切ったときに、そういう表記の一致が起こる、というだけです。

IPv6 では IPv4 の 32bit に対し、128bit にアドレスが拡張されました。人間が読み書きするためのアドレス表記も少し作法が変わり、区切り文字が .(ドット)から :(コロン)に、区切る単位が 8bitずつから 16bitずつに、そして 10進数から 16進数に変わりました。

例えば、

2001:db8:1234:5678:90ab:cdef:4321:fedc

といった書き方をします。この表記は少しだけ省略形が入っていて、db8 の区切りは実際は 0db8 ですが、先頭の 0 が省略されるので各区切りが 4ケタのところ、ここだけ 3ケタになっています。本来は 16進数なので識別のために xなどを付けたいところですが、IPv6アドレスでは基本的に 16進数しか使わないので現れる数字は 16進数であると解釈します。

これを 10進数で書くことももちろん可能です。(使わないけど)

8193:3512:4660:22136:37035:52719:17185:65244

なんか、数字ばかり並ぶし各区切りごとにケタが違ってて見づらいですよね。でも IPv4アドレスって、日常的にこういう表記をしてるんです。

ついでなので IPv4アドレス風に、8bitずつドット区切り10進数で書いてみましょうか。

32.1.13.184.18.52.86.120.144.171.205.239.67.33.254.220

もうわけがわかりません。IPv6アドレスの表記にこの作法が引き継がれなくて本当によかったと思います。

Google の IPv6 の使い方を見ていると、サーバに割り当てるアドレスは 16進数で表現したアドレスが 10進数で使う数字(つまり 0~9 の 10種類)だけで表せるアドレスを使うようにルール作りしているようです。機械(サーバやルータ)にとってはどうでもいいことなんですが、設定作業を行う人間が間違えにくいように、テンキーだけで入力できるように、電話窓口で伝えられるように、などの理由があるんだと思いますが人間臭さを感じさせない企業の代名詞とも言える Google が、インフラではものすごく人間臭いことをやってるんだな、とちょっとおもしろい実例なので紹介しておきます。なおネットワーク(ルータやスイッチ)など、裏ではこのルールは使われていません。


さいごに


技術的な小難しい話題でしたが、最後まで読んでいただいてありがとうございました。

よければ ↓ にある、♡ をクリックしていただけると励みになります。質問のコメントも歓迎です。

いいなと思ったら応援しよう!