hexdump / xxd 入門 - バイナリを16進数で覗く

hexdump / xxd 入門 - バイナリを16進数で覗く

hexdump・xxd・od で何ができる?

結論: 3 つともファイルのバイトを 16 進数で表示するツール。実務ではまず hexdump -Cxxd を使い、編集が必要なら xxd -r を使う。od は移植性が必要な場面の保険。

  • ファイルの中身を 1 バイト単位の 16 進数 で確認できる
  • 目に見えない 制御文字・改行コード(CRLF)・BOM を発見できる
  • xxd -r16 進ダンプを編集してバイナリに戻す ことができる

3 ツールの一言まとめ

  • hexdump -C … 16 進 + ASCII の定番ビュー(Linux で最も使われる)
  • xxd … 見やすく、-r で逆変換・-i で C 配列化までできる多機能
  • od … POSIX 標準で最古。移植性が最優先のときの保険

前提(対象環境)

  • OS: Ubuntu / 一般的な Linux
  • hexdump / od は coreutils・bsdmainutils 系で標準提供
  • xxdvim-common パッケージに含まれる(Ubuntu では vim 導入時に同梱)

なぜバイナリを16進数で見る必要があるのか?

結論: テキストエディタでは見えない「目に見えないバイト」を確認するため。改行コードの違い、先頭の BOM、末尾の余分な空白、壊れたエンコーディングは 16 進ダンプで初めて姿を現す。

「スクリプトが動かない」「diff が一致しない」「ファイル判定がおかしい」——こうした問題の裏には、画面に表示されないバイト が潜んでいることが多い。

  • Windows 由来の改行 \r\n(CRLF)が混入している
  • UTF-8 ファイルの先頭に BOM(EF BB BF)が付いている
  • 全角スペースや制御文字が紛れ込んでいる

これらはテキストエディタでは判別しづらいが、16 進ダンプなら 1 バイトずつ正確に観測できる。

hexdump の基本 - まず -C を使う

結論: hexdump のデフォルト出力は 16 ビット語をバイトスワップして表示するため読みにくい。実務では必ず -C(canonical)を付け、左に 16 進・右に ASCII を並べて読む。

サンプルファイルを用意する。

$ printf 'Hello, World!\n' > demo.txt

-C を付けると、オフセット・16 進バイト列・ASCII が 1 行に並ぶ。

$ hexdump -C demo.txt
00000000  48 65 6c 6c 6f 2c 20 57  6f 72 6c 64 21 0a        |Hello, World!.|
0000000e

左の 00000000 はファイル先頭からのオフセット(16 進)、中央が各バイトの 16 進値、右の |...| が印字可能文字の ASCII 表現(印字不能は .)。

-C を付けないと読みにくい

$ hexdump demo.txt
0000000 6548 6c6c 2c6f 5720 726f 646c 0a21
000000e

これはリトルエンディアン環境で 2 バイトを 1 語としてバイトスワップした表示。48 656548 と入れ替わって見える。混乱の元なので、人間が読むときは -C を使う。

よく使うオプション:

  • -n <length>: 先頭 N バイトだけ表示
  • -s <offset>: 先頭から N バイトスキップして表示
  • -v: 同一行の繰り返しを * で省略せず全表示
$ hexdump -C -n 16 -s 0 demo.txt

xxd の基本と便利な使い方

結論: xxd は素の実行で見やすいダンプを出す。真価は -r(16 進→バイナリ復元)・-p(プレーン 16 進)・-i(C 配列出力)にあり、hexdump にはできない逆変換まで担える。

素の xxd は 2 バイトごとにグループ化された 16 進と右側の ASCII を表示する。

$ xxd demo.txt
00000000: 4865 6c6c 6f2c 2057 6f72 6c64 210a            Hello, World!.

プレーン16進で取り出す(-p)

-p(plain)は区切りなしの連続した 16 進文字列を出す。スクリプトで扱いやすい。

$ xxd -p demo.txt
48656c6c6f2c20576f726c64210a

16進からバイナリに戻す(-r)

xxd 最大の武器が逆変換 -r。ダンプを編集してから元のバイナリに戻せる。

$ xxd demo.txt | xxd -r
Hello, World!

プレーン 16 進から戻すときは -p も合わせる。

$ echo '48656c6c6f0a' | xxd -r -p
Hello

C言語の配列として出力(-i)

-i(include)はファイルを C のバイト配列として出力する。ファームウェアやテスト用データの埋め込みに便利。

$ xxd -i demo.txt
unsigned char demo_txt[] = {
  0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64,
  0x21, 0x0a
};
unsigned int demo_txt_len = 14;

よく使うオプション:

  • -l <length>: 先頭 N バイトだけ表示
  • -s <offset>: 開始位置を指定
  • -c <cols>: 1 行あたりのバイト数(既定 16)
  • -g <bytes>: グループ化するバイト数(既定 2)

od はどんなときに使うのか?

結論: od(octal dump)は POSIX 標準で最も移植性が高い。組み込み Linux や最小構成で hexdumpxxd が無い環境でも使える。od -A x -t x1zhexdump -C 相当の出力になる。

od は名前の通り元は 8 進ダンプだが、-t で表示形式を、-A でオフセットの基数を指定できる。

$ od -A x -t x1z demo.txt
000000 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 0a  >Hello, World!.<
00000e
  • -A x: オフセットを 16 進で表示(d で 10 進、o で 8 進)
  • -t x1: 1 バイト単位の 16 進で表示
  • z: 行末に ASCII 表現を併記

その他のよく使う形式:

  • od -c: 文字とエスケープ表記(\n \t 等)で表示
  • od -An -t x1: オフセットを省略して 16 進バイトのみ

od の出力は POSIX で仕様が定められているため、スクリプトの移植性を重視するなら od -A n -t x1 のように od を選ぶ価値がある。

3ツールをどう使い分けるか?

結論: 日常の確認は hexdump -Cxxd、バイナリを編集するなら xxd -r、移植性が要るスクリプトなら od。迷ったら hexdump -C で十分。

用途 推奨ツール
とにかく中身を見たい hexdump -C
見やすさ重視・グループ表示 xxd
16 進を編集してバイナリに戻す xxd -r
C 配列に埋め込む xxd -i
移植性・最小環境 od -A x -t x1z

実務での使いどころ

結論: 改行コードの混入・BOM の有無・バイナリの直接編集が代表的な実務シーン。いずれも 16 進ダンプでなければ確実には判断できない。

CRLF(改行コード)の混入を見つける

\r\n(CRLF)が混ざると 0d 0a のように 0d が現れる。Unix の改行 \n0a のみ。

$ printf 'line1\r\nline2\n' | xxd
00000000: 6c69 6e65 310d 0a6c 696e 6532 0a          line1..line2.

310d 0a6c0d が CRLF の証拠。右側 ASCII では . としか見えないバイトを正確に特定できる。

UTF-8 の BOM を確認する

ファイル先頭に EF BB BF があれば UTF-8 BOM 付き。

$ hexdump -C bom.txt
00000000  ef bb bf 68 69 0a                                 |...hi.|
00000006

先頭 3 バイト ef bb bf が BOM。シェルスクリプトの先頭にこれが付くと #!/bin/bash が正しく解釈されず、実行エラーの原因になる。

バイナリを直接編集する(ラウンドトリップ)

xxd でダンプ → エディタで 16 進を書き換え → xxd -r で戻す、という流れで 1 バイト単位の編集ができる。

$ xxd demo.txt > demo.hex
# demo.hex を編集(例: 48 を 4a に変更)
$ xxd -r demo.hex > demo_edited.txt

xxd -r で戻すときはオフセット列とバイト列の整合に注意。バイト数を変えるとオフセットがずれて意図しない結果になることがある。1 バイト置換のような最小限の編集にとどめるのが安全。

トラブルシューティング

結論: xxd: command not foundvim-common 未導入が原因。出力が読みにくいときは hexdump-C を付け忘れていないか確認する。

xxd: command not found

xxdvim-common(または xxd)パッケージに含まれる。最小構成の環境では未導入のことがある。

$ sudo apt install xxd

xxd が使えない環境では od -A x -t x1z または hexdump -C で代替する。

hexdump の出力が想定と違う

-C 無しのデフォルトは 16 ビット語のバイトスワップ表示。ASCII が並ばず読みにくいときは -C の付け忘れを疑う。

大きなファイルで同じ行が * に省略される

hexdump / od は同一内容の行を * で省略する。全行を確認したいときは -v を付ける。

$ hexdump -C -v largefile.bin | head

次に読む