エンディアン

2 バイト以上のデータをメモリやファイルに格納する際の、バイトの並び順を定める規約

低レイヤデータ表現ネットワーク

エンディアンとは

エンディアン (endianness) は、2 バイト以上の数値をメモリやファイル、ネットワーク上に並べるときの「バイトの順序」を定める規約である。最上位バイトを先頭に置く方式をビッグエンディアン、最下位バイトを先頭に置く方式をリトルエンディアンと呼ぶ。

同じ数値 0x12345678 (4 バイト) でも、並び順は方式によって正反対になる。

数値: 0x12345678 (10 進では 305419896)

ビッグエンディアン (上位バイトが先)
  アドレス: +0   +1   +2   +3
  バイト:   12   34   56   78

リトルエンディアン (下位バイトが先)
  アドレス: +0   +1   +2   +3
  バイト:   78   56   34   12

人間が数字を左から書く感覚に近いのはビッグエンディアンだが、x86 / x86-64 や多くの ARM 構成はリトルエンディアンを採用している。このため「直感的でない並び順」が実務の標準になっている点が、つまずきの最初の一歩になる。

なぜ実務で問題になるのか

単一のマシン内で完結する処理なら、エンディアンを意識する場面はほとんどない。CPU が一貫した方式で読み書きするため、プログラマからは透過的に見える。問題が表面化するのは、バイト列が異なる環境をまたいで移動するときである。

  • 異なる CPU アーキテクチャ間でバイナリデータを交換する
  • ファイルフォーマットやネットワークプロトコルを自前でパースする
  • メモリダンプやパケットキャプチャを直接読む

ネットワーク通信では歴史的にビッグエンディアンが標準とされ、これを「ネットワークバイトオーダー」と呼ぶ。一方、送受信するホストの多くはリトルエンディアンであるため、ソケット API では htons / htonl (host to network) や ntohs / ntohl (network to host) といった変換関数でバイト順を明示的にそろえる。この変換を忘れると、ポート番号や IP アドレスが化けるという典型的なバグになる。

エンディアンの確認方法

自分が動かしている環境がどちらかは、1 つの整数を 1 バイトずつ覗けば判定できる。

#include <stdio.h>
int main(void) {
    unsigned int x = 1;            // 0x00000001
    unsigned char *p = (unsigned char *)&x;
    // 先頭バイトが 1 ならリトルエンディアン
    printf("%s\n", p[0] == 1 ? "little-endian" : "big-endian");
    return 0;
}

0x00000001 の先頭バイトが 01 ならリトルエンディアン、00 ならビッグエンディアンである。

ビッグエンディアンとリトルエンディアンの比較

観点ビッグエンディアンリトルエンディアン
並び順上位バイトが先頭下位バイトが先頭
主な採用例ネットワークプロトコル、一部の RISC、JVM の内部表現x86 / x86-64、多くの ARM 構成
ダンプの読みやすさ人間の数字表記に近い慣れないと逆順に見える
型のサイズ拡張先頭がずれる先頭アドレスが変わらず拡張しやすい

どちらが優れているという絶対的な優劣はない。リトルエンディアンは「同じアドレスから読み始めても型の幅を変えやすい」という実装上の利点があり、ビッグエンディアンは「人間が読んだときの直感性」と「プロトコル標準としての一貫性」で支持されてきた。

よくある落とし穴

  • 変換忘れ: ネットワーク送受信や異機種間のファイル交換で hton* / ntoh* 相当の変換を省くと、値が逆順に化ける。単一環境のテストでは再現しないため発見が遅れやすい。
  • バイナリの直接比較: バイト列をそのまま比較・ハッシュ化すると、エンディアンの違うシステム同士で不一致になる。交換用フォーマットでは並び順を仕様で固定する。
  • キャストでの覗き見: intchar* にキャストして 1 バイトずつ扱うコードは、エンディアン依存になりやすい。移植性を保つにはビットシフトで明示的に組み立てる。

こうした事故を避ける最も確実な方法は、自前でバイト列を組み立てず、並び順を仕様で固定したシリアライズ形式に委ねることである。データのメモリ上の並びについては メモリレイアウト、相互運用を前提とした変換の考え方は エンコーディングとシリアライゼーションProtocol Buffers もあわせて参照してほしい。

この記事は役に立ちましたか?

関連用語

関連する記事