16進数のバイト列が逆に見える理由

16進数の値をメモリダンプ、バイナリファイル、通信ログなどで確認すると、期待した順番と逆に見えることがあります。たとえば、数値としては0x12345678のはずなのに、バイト列としては78 56 34 12のように表示される場合です。

これはデータが壊れているとは限りません。多くの場合、エンディアン、つまりバイトオーダーの違いが原因です。

この記事の要点

手元の16進数を確認したい方へ

Big EndianとLittle Endianの並び、10進数、2進数をまとめて確認できます。

エンディアン変換ツールを使う

まず確認する例

数値0x12345678を4バイトの値として考えます。Big Endianでは上位バイトから、Little Endianでは下位バイトから順番に並びます。

同じ4バイト値の見え方

Big Endian:12 34 56 78
Little Endian:78 56 34 12

このため、メモリ上のバイト列だけを見ると、値が逆向きに保存されているように見えることがあります。ただし、読み込む側が同じエンディアンを前提にしていれば、値そのものは0x12345678として正しく扱われます。

逆に見えるのは「バイト単位」

エンディアン変換でよくある誤解は、数字やビットを1文字ずつ反転してしまうことです。0x12345678をLittle Endianにするとき、87654321にはしません。

正しくは、2桁の16進数を1バイトとして区切り、バイト単位で並び替えます。

12 34 56 78

78 56 34 12

16進数では2桁で1バイトを表します。エンディアンを考えるときは、まず2桁ずつ区切って見ることが大切です。

よくある間違い

間違い正しい考え方
1文字ずつ反転する12345678876543212桁ずつ区切ってバイト単位で反転する
ビット順を反転する00010010を逆順にする通常のエンディアン変換ではビット順は変えない
何バイトの値か確認しない123456をそのまま反転する2バイト、4バイト、8バイトなどの単位を確認する
文字列のHEXと数値のHEXを混同する31 32 33を数値123と読む文字コード由来のHEXか数値由来のHEXか確認する

特に大切なのは、何バイトの値として扱うかです。2バイトの値と4バイトの値では、並び替える単位が変わります。

2バイト・4バイト・8バイトでの違い

同じ16進数でも、何バイトの値として読むかによって見え方が変わります。

Big EndianLittle Endian
2バイト12 3434 12
4バイト12 34 56 7878 56 34 12
8バイト01 23 45 67 89 AB CD EFEF CD AB 89 67 45 23 01

エンディアン変換では値全体をバイト単位で並び替えます。途中の1バイトの中身までは反転しません。

メモリダンプで逆に見える場合

メモリダンプでは、CPUが実際にメモリへ保存しているバイト列が表示されます。Little Endianの環境では、4バイト整数0x1234567878 56 34 12のように見えることがあります。

開発中にデバッガやバイナリエディタで値を見るときは、表示されているものがメモリ上の並びなのか、数値として解釈された表示なのかを分けて考えます。

ファイル解析で確認するポイント

バイナリファイルを読む場合、ファイル形式ごとにエンディアンが決まっていることがあります。たとえば4バイトの領域が78 56 34 12だった場合、Little Endianとして読めば数値は0x12345678です。一方、Big Endianとして読めば0x78563412になります。

同じバイト列でも、エンディアンの前提が違うと数値が変わります。ファイル仕様書やデータフォーマットの説明で、Big EndianなのかLittle Endianなのかを確認することが重要です。

通信データで確認するポイント

通信プロトコルでは、ネットワークバイトオーダーとしてBig Endianが使われることがあります。一方、PCやサーバー内部ではLittle EndianのCPUがよく使われます。そのため、内部で使っている数値を通信データとして送るときに、エンディアン変換が必要になることがあります。

この確認をしないまま数値を読むと、本来の値とまったく違う数値に見えることがあります。

文字列のHEXとは区別する

エンディアンは、主に複数バイトの数値をどう並べるかの話です。一方、文字列をHEXで表した場合は、文字コードのバイト列として扱います。

文字列と数値は別物

文字列1234をASCIIでHEXにすると31 32 33 34です。これは数値0x1234とは別物です。

数値のエンディアン変換をしているのか、文字列の文字コードを確認しているのかを混同しないようにしましょう。

ツールで確認する方法

エンディアン変換ツールを使うと、16進数のバイト列をBig EndianとLittle Endianで確認できます。使うときは、次の順番で確認すると分かりやすくなります。

  1. 16進数を2桁ずつ区切る
  2. 何バイトの値として扱うか確認する
  3. Big Endianの並びを確認する
  4. Little Endianの並びを確認する
  5. 10進数や2進数としての解釈も確認する

特に0x123456780x000000010xFF000000のような値で試すと、バイト順の違いが見えやすくなります。

よくある質問

16進数を逆にすればLittle Endianになりますか?

1文字ずつ逆にするのではありません。16進数は2桁で1バイトを表すため、通常は2桁ずつ区切ってバイト単位で並び替えます。

エンディアン変換ではビットも反転しますか?

通常は反転しません。エンディアンは複数バイトの値を保存・送信するときのバイトの並び順を指し、各バイト内のビット順を逆にするものではありません。

12345678と78 56 34 12は同じ値ですか?

前提によります。78 56 34 12をLittle Endianの4バイト値として読む場合は、数値として0x12345678になります。Big Endianとして読む場合は0x78563412になります。

何バイト単位で変換すればよいですか?

元データの仕様によります。2バイト整数、4バイト整数、8バイト整数など、データ型やファイル仕様に合わせて確認する必要があります。

文字列のHEXにもエンディアンは関係しますか?

通常の文字列HEXでは、文字コードのバイト列をそのまま確認することが多く、数値のエンディアンとは分けて考えます。ただしUTF-16やUTF-32ではBOMやバイト順が関係する場合があります。