エンディアン: ビッグエンディアンとリトルエンディアンのバイト順序

ビッグエンディアンとリトルエンディアンのバイト順序を理解。マルチバイト値がメモリにどう格納されるか、クロスプラットフォームコードでなぜ重要かを解説します。

Multi-byte BinaryByte-Ordered BinaryHardware

詳細な説明

エンディアンは、マルチバイト値のバイトがメモリに格納される順序を表します。一見単純な概念ですが、クロスプラットフォームソフトウェア、ネットワークプログラミング、バイナリファイル解析における主要なバグの原因です。

ビッグエンディアン(ネットワークバイトオーダー):

最上位バイトが最も低いメモリアドレスに格納されます。数値 0x12345678 は以下のように格納されます:

Address:  0x00  0x01  0x02  0x03
Value:    0x12  0x34  0x56  0x78

これは人間が数値を書く方法(最上位桁が先)と一致します。TCP/IP ネットワークプロトコルはビッグエンディアンを使用するため、「ネットワークバイトオーダー」とも呼ばれます。

リトルエンディアン(Intel バイトオーダー):

最下位バイトが最も低いメモリアドレスに格納されます。同じ 0x12345678 は以下のように格納されます:

Address:  0x00  0x01  0x02  0x03
Value:    0x78  0x56  0x34  0x12

ほとんどの最新 CPU(x86、x86-64、多くの ARM 構成)はリトルエンディアンを使用します。

リトルエンディアンが存在する理由:

リトルエンディアンは特定のハードウェア操作を簡素化します。32ビット整数を16ビット整数にキャストする場合、値はすでに同じメモリアドレスにあるため、ポインタの調整が不要です。加算も最下位バイトから自然に上位へ進行します。

エンディアンが問題を引き起こす場面:

  • ネットワーク通信: Intel マシン(リトルエンディアン)から SPARC マシン(ビッグエンディアン)に送信されたデータは、バイトスワップしないと文字化けします。htonl()ntohl() などの関数がこれを処理します。
  • バイナリファイル形式: ファイル形式はエンディアンを指定しています。BMP ファイルはリトルエンディアン。TIFF ファイルにはエンディアンマーカーが含まれます。間違ったバイト順でファイルを読むと無意味な値になります。
  • Hexdump 分析: x86 システムのメモリの Hexdump を読む際、32ビット整数 0x0000000101 00 00 00 として表示され、00 00 00 01 ではありません。

コードでエンディアンを検出する:

JavaScript: new Uint8Array(new Uint32Array([1]).buffer)[0] === 1 はリトルエンディアンシステムで true を返します。Python: import sys; sys.byteorder'little' または 'big' を返します。

ユースケース

組み込みシステムエンジニアは、リトルエンディアンの ARM プロセッサとビッグエンディアンのネットワークプロトコルや周辺機器間の通信ドライバを書く際に、エンディアン変換を処理します。

Try It — Number Base Converter

フルツールを開く