3.2 バイトオーダー
レルムの命令で!バイトの並び順は2種類とします。今後、Lame and Magnificent と呼ばれるようになります。
というのは冗談ですが、本当にどちらか一方が優れているのです。:-)
あなたのコンピュータは、あなたの背後でバイトを逆順に保存しているかもしれないのです。そうなんです。誰もあなたに言いたくはなかったのです。
つまり、2バイトの16進数、たとえば b34f を表現する場合、b3 と 4f の2バイトに続けて格納する、というのがインターネットの世界の共通認識になっているのです。これは理にかなっているし、ウィルフォード・ブリムリーも言うように、正しい行為です。このように、大きい方の端が先になるように格納された数字をビッグエンディアン(Big-Endian)と呼びます。
残念ながら、世界中に散在する一部のコンピュータ、すなわちインテルまたはインテル互換のプロセッサを搭載したものは、バイトを逆に格納しているため、b34f は 4f と b3 の連続したバイトとしてメモリに格納されることになります。この記憶方式をリトルエンディアン(Little-Endian)と呼びます。
でも、ちょっと待ってください!用語の説明はまだ終わっていないのです。もっとまともなビッグエンディアンはネットワークバイトオーダーとも呼ばれ、私たちネットワーク系が好む順序だからです。
コンピュータはホストバイトオーダーで数字を記憶しています。インテル 80x86 であれば、ホストバイト順はリトルエンディアンです。モトローラ 68K の場合は、ビッグエンディアンです。PowerPC なら、ホストバイトの並びは......まあ、人それぞれですね。
パケットを作成するときやデータ構造を埋めるときに、2バイトや4バイトの数値がネットワークバイトオーダーになっていることを確認する必要があることがよくあります。しかし、ネイティブなホストバイトオーダーがわからない場合、どのようにすればよいのでしょうか。
朗報です。ホストのバイトオーダーが正しくないと仮定して、値をネットワークバ イトオーダーに設定するための関数を常に実行するようにすればよいのです。この関数は、必要であれば魔法のような変換を行い、エンディアンが異なるマシンにもコードを移植することができます。
よしよし。変換できる数値は、short(2バイト)と long(4バイト)の2種類です。これらの関数は、符号なしのバリエーションでも動作します。例えば、short をホストバイトオーダーからネットワークバイトオーダーに変換したいとします。まず "h" でホスト、その後に "to" をつけます。そして、"n" は "network"、"s" は "short" を表します。h-to-n-s または htons()(読み方: "ホストからネットワークへのショート")です。
簡単すぎるくらいに...。
"n"、"h"、"s"、"l" の組み合わせは、本当にくだらないものを除いて、すべて使うことができるのです。たとえば、stolh()("Short to Long Host")という関数はありません---とにかく、このパーティーでは。しかし、あるのです。
| 関数 | 説明 |
|---|---|
htons() | host to network short |
htonl() | host to network long |
ntohs() | network to host short |
ntohl() | network to host long |
基本的には、送出する前にネットワークバイトオーダーに変換し、送出後にホストバイトオーダーに変換します。
64bit のバリエーションは知らないです、すみません。また、浮動小数点をやりたい場合は、ずっと下のシリアライゼーションの章をチェックしてください。
この文書では、特に断らない限り、数値はホストバイトオーダーであると仮定しています。