Linuxを使っていて 「16進数(hex)を文字列に変換したい」 「文字列を16進数表記にしたい」 と思ったことはありませんか?
- バイナリファイルをデバッグするとき
- ネットワークプロトコルのデータを確認するとき
- 文字コードの問題を切り分けたいとき
など、Linuxで16進数⇔文字列の変換は意外と出番が多いです。
この記事では、xxd
、echo
、printf
などを使って、Linuxで16進数と文字列を簡単に変換する方法をわかりやすく解説します。
16進数と文字列変換の基本概念

なぜ16進数変換が必要?
バイナリデータの可視化
- バイナリファイルは直接読めないため、16進数で内容を確認
- ネットワークパケットの中身を解析
- メモリダンプの内容確認
文字コードの調査
- 文字化けの原因特定
- エンコーディング方式の確認
- バイト単位でのデータ比較
デバッグとトラブルシューティング
- プログラムが出力する生データの確認
- ファイル形式の検証
- データ破損の有無チェック
16進数表現の基本
ASCII文字の16進数例:
- ‘A’ = 0x41 (65)
- ‘a’ = 0x61 (97)
- ‘0’ = 0x30 (48)
- スペース = 0x20 (32)
- 改行 = 0x0A (10)
日本語文字の例(UTF-8):
- ‘あ’ = 0xE3 0x81 0x82
- ‘ん’ = 0xE3 0x82 0x93
文字列を16進数に変換する方法
xxdコマンドを使う方法
最もシンプルな変換:
echo -n "hello" | xxd -p
出力例:
68656c6c6f
オプションの詳細:
-n
:echoが末尾に改行をつけないオプション-p
:16進数をプレーン形式(アドレス情報なし)で出力
日本語の変換例:
echo -n "こんにちは" | xxd -p
出力例:
e38193e38293e381abe381a1e381af
より詳細な表示形式
標準のxxd表示(アドレス付き):
echo -n "hello world" | xxd
出力例:
00000000: 6865 6c6c 6f20 776f 726c 64 hello world
16バイトごとに改行(デフォルト):
echo -n "This is a longer text for demonstration" | xxd
出力例:
00000000: 5468 6973 2069 7320 6120 6c6f 6e67 6572 This is a longer
00000010: 2074 6578 7420 666f 7220 6465 6d6f 6e73 text for demons
00000020: 7472 6174 696f 6e tration
printf と od を組み合わせる方法
od コマンドによる16進数表示:
printf "hello" | od -An -tx1
出力例:
68 65 6c 6c 6f
オプションの説明:
-An
:アドレス表示なし-tx1
:1バイトずつ16進数で表示
文字も同時に表示:
printf "hello" | od -tx1z
出力例:
0000000 68 65 6c 6c 6f >hello<
hexdump コマンドを使う方法
hexdump による表示:
echo -n "hello" | hexdump -C
出力例:
00000000 68 65 6c 6c 6f |hello|
00000005
カスタム形式での表示:
echo -n "hello" | hexdump -e '1/1 "%02x"'
出力例:
68656c6c6f
16進数を文字列に変換する方法

xxd -r による逆変換
基本的な逆変換:
echo -n "68656c6c6f" | xxd -r -p
出力:
hello
日本語の逆変換:
echo -n "e38193e38293e381abe381a1e381af" | xxd -r -p
出力:
こんにちは
echo -e によるエスケープシーケンス
\xXX 形式による変換:
echo -e "\x68\x65\x6c\x6c\x6f"
出力:
hello
改行文字も含む例:
echo -e "\x48\x65\x6c\x6c\x6f\x0a\x57\x6f\x72\x6c\x64"
出力:
Hello
World
printf による精密な制御
printf での16進数変換:
printf "\x68\x65\x6c\x6c\x6f\n"
変数を使った動的変換:
hex_string="68656c6c6f"
printf "${hex_string}" | xxd -r -p
実践的な活用例
ファイル全体の16進数変換
バイナリファイルを16進数表示:
xxd sample.bin
出力例:
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0300 3e00 0100 0000 1010 0000 0000 0000 ..>.............
ファイルサイズが大きい場合の部分表示:
# 最初の64バイトのみ表示
xxd -l 64 large_file.bin
# 特定の位置から表示
xxd -s 100 -l 32 large_file.bin
16進数ファイルからバイナリファイルの復元
xxd形式のファイルから復元:
xxd -r hexdump.txt > restored.bin
プレーン16進数から復元:
xxd -r -p plain_hex.txt > restored.bin
ネットワークパケット解析
tcpdump出力の16進数部分を抽出:
# TCPパケットの16進数データ
echo "474554202f20485454502f312e310d0a486f73743a206578616d706c652e636f6d0d0a0d0a" | xxd -r -p
出力:
GET / HTTP/1.1
Host: example.com
Wiresharkからコピーした16進数データの変換:
# スペース区切りの16進数を処理
echo "47 45 54 20 2f 20 48 54 54 50" | tr -d ' ' | xxd -r -p
URL エンコード/デコード
URLエンコードされた文字列の解析:
# %E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF を変換
echo "E381AEE38293E381ABE381A1E381AF" | xxd -r -p
文字列からURLエンコード用の16進数生成:
echo -n "こんにちは" | xxd -p | sed 's/../%&/g'
出力:
%e3%81%93%e3%82%93%e3%81%ab%e3%81%a1%e3%81%af
文字エンコーディングとの組み合わせ

異なる文字エンコーディングでの変換
Shift_JIS エンコーディング:
echo -n "こんにちは" | iconv -f UTF-8 -t SHIFT_JIS | xxd -p
EUC-JP エンコーディング:
echo -n "こんにちは" | iconv -f UTF-8 -t EUC-JP | xxd -p
16進数からShift_JISに変換:
echo -n "82b1828293c982bf82cd82cd" | xxd -r -p | iconv -f SHIFT_JIS -t UTF-8
Base64との組み合わせ
文字列 → 16進数 → Base64:
echo -n "hello" | xxd -p | xxd -r -p | base64
Base64 → 16進数 → 文字列:
echo "aGVsbG8=" | base64 -d | xxd -p
高度な変換テクニック
スクリプトによる自動変換
hex_convert.sh(汎用変換スクリプト):
#!/bin/bash
# 16進数と文字列の相互変換スクリプト
show_help() {
cat << EOF
使用法: $0 [オプション] <入力>
オプション:
-s, --string-to-hex 文字列を16進数に変換
-h, --hex-to-string 16進数を文字列に変換
-f, --file ファイルを処理
--help このヘルプを表示
例:
$0 -s "hello" # 文字列を16進数に変換
$0 -h "68656c6c6f" # 16進数を文字列に変換
$0 -f -s file.txt # ファイル内容を16進数に変換
EOF
}
string_to_hex() {
if [ "$FILE_MODE" = true ]; then
xxd -p "$1" | tr -d '\n'
else
echo -n "$1" | xxd -p
fi
echo
}
hex_to_string() {
if [ "$FILE_MODE" = true ]; then
xxd -r -p "$1"
else
echo -n "$1" | xxd -r -p
fi
echo
}
# オプション解析
MODE=""
FILE_MODE=false
while [[ $# -gt 0 ]]; do
case $1 in
-s|--string-to-hex)
MODE="s2h"
shift
;;
-h|--hex-to-string)
MODE="h2s"
shift
;;
-f|--file)
FILE_MODE=true
shift
;;
--help)
show_help
exit 0
;;
-*)
echo "未知のオプション: $1"
show_help
exit 1
;;
*)
break
;;
esac
done
# 実行
case "$MODE" in
"s2h")
string_to_hex "$1"
;;
"h2s")
hex_to_string "$1"
;;
*)
echo "モードを指定してください (-s または -h)"
show_help
exit 1
;;
esac
大量データの効率的な処理
大きなファイルの部分的な変換:
# ファイルの特定部分(100バイト目から200バイト)を16進数表示
dd if=large_file.bin bs=1 skip=100 count=200 2>/dev/null | xxd
ストリーミング処理:
# パイプラインでの連続処理
tail -f logfile | xxd -p | while read hex; do
echo "Hex: $hex"
echo -n "$hex" | xxd -r -p
echo "---"
done
正規表現との組み合わせ
16進数パターンの抽出:
# ログファイルから16進数パターンを抽出
grep -o '[0-9a-fA-F]\{2,\}' logfile.txt | while read hex; do
echo "Found hex: $hex"
echo -n "$hex" | xxd -r -p 2>/dev/null && echo
done
特定パターンの検索と変換:
# HTTPヘッダーの16進数表現を検索
echo "474554202f20485454502f312e31" | xxd -r -p | grep -o "HTTP/[0-9]\.[0-9]"
トラブルシューティング

よくあるエラーと対処法
不正な16進数文字列:
# エラーが発生する例
echo "invalid_hex" | xxd -r -p
# 有効な16進数かチェック
if [[ "$hex_string" =~ ^[0-9a-fA-F]+$ ]]; then
echo -n "$hex_string" | xxd -r -p
else
echo "無効な16進数文字列: $hex_string"
fi
文字エンコーディングの問題:
# 文字化けが発生した場合
echo -n "問題の文字列" | xxd -p
# → 出力された16進数を別のエンコーディングで試す
echo -n "e5958fe9a18c" | xxd -r -p | iconv -f UTF-8 -t SHIFT_JIS
改行文字の処理:
# 改行を含む変換
echo "hello world" | xxd -p # 改行も16進数化される
# 改行を除去して変換
echo -n "hello world" | xxd -p # 改行なしで変換
パフォーマンス最適化
大きなファイルの効率的な処理:
# バッファサイズを指定して高速化
xxd -l 1048576 large_file.bin # 1MBずつ処理
# 並列処理
split -b 1M large_file.bin chunk_
for chunk in chunk_*; do
xxd "$chunk" > "${chunk}.hex" &
done
wait
まとめ
基本コマンドまとめ
文字列 → 16進数:
echo -n "text" | xxd -p
16進数 → 文字列:
echo -n "hex" | xxd -r -p
ファイル全体の変換:
xxd filename.bin # ファイルを16進数表示
xxd -r hexfile.txt > binary.bin # 16進数ファイルをバイナリに復元
実用的な応用例
デバッグとトラブルシューティング:
- バイナリファイルの内容確認
- ネットワークパケットの解析
- 文字エンコーディングの問題調査
データ処理と変換:
- URLエンコード/デコードの補助
- 異なる文字エンコーディング間の変換
- Base64との組み合わせ処理
システム管理:
- ログファイルの解析
- 設定ファイルのバイナリ部分確認
- メモリダンプの分析
重要なポイント
文字エンコーディングの注意:
- UTF-8、Shift_JIS、EUC-JPなどで16進数表現が異なる
- 文字化けが発生した場合は、エンコーディングを確認
改行文字の扱い:
echo -n
で改行を除去printf
で厳密な制御- 改行文字も16進数で確認可能
効率性の考慮:
- 大きなファイルは部分的に処理
- ストリーミング処理の活用
- 並列処理による高速化
これらの知識があれば、Linuxでの16進数と文字列の変換を自在に操れるようになります。
ログ解析、ネットワークデバッグ、文字化け調査など、様々な場面でぜひ活用してみてください!
コメント