Base64 vs 16進数エンコード

Base64と16進数(hex)エンコードを比較。サイズの違い、可読性のトレードオフ、それぞれのエンコード形式を使うべき場面を詳しく解説します。

Concept

詳細な説明

Base64と16進数は、どちらもバイナリデータを印刷可能なテキストとして表現する方法ですが、効率性、可読性、一般的な用途で大きく異なります。

1バイトをエンコードした場合のサイズ比較:

  • 元のデータ:1バイト(8ビット)
  • 16進数:2文字(各16進数字は4ビットを表現)
  • Base64:約1.33文字(各Base64文字は6ビットを表現)

100バイトをエンコードした具体例:

  • 16進数:200文字(2倍に膨張)
  • Base64:136文字(パディング込みで約1.33倍に膨張)

つまり、同じデータに対してBase64は16進数より約33%コンパクトです。埋め込み画像やファイル添付のような大きなペイロードでは、この差は無視できません。

可読性: 短い値では16進数の方が人間にとって読みやすいです。48656C6C6F のような16進文字列は、文字ごとに頭の中でデコードできます(0x48 = H, 0x65 = e など)。SGVsbG8= のようなBase64文字列はデコードしない限り意味不明です。

16進数はバイトレベルでの操作も容易です。16進文字2つが正確に1バイトに対応するため、個々のバイトの検査、ハッシュの比較、ファイルシグネチャ(マジックバイト)の識別が簡単です。

16進数を使うべきケース:

  • ハッシュ値(MD5、SHA-256)の表示。慣習として16進数が使われます。
  • 生のバイト、メモリアドレス、パケット内容を示すデバッグ出力
  • CSSのカラーコード(#FF5733
  • コンパクトさより可読性が重要な短い識別子

Base64を使うべきケース:

  • テキストベースプロトコル(JSON、XML、メール)でのバイナリデータ転送
  • HTML/CSSへのファイル埋め込み(data URI)
  • API認証トークンや資格情報
  • エンコード後のサイズを最小限にしたい場面

JavaScriptでのエンコード比較:

const bytes = new Uint8Array([72, 101, 108, 108, 111]);

// Hex
const hex = Array.from(bytes).map(b => b.toString(16).padStart(2, "0")).join("");
// "48656c6c6f"

// Base64
const base64 = btoa(String.fromCharCode(...bytes));
// "SGVsbG8="

どちらも暗号化ではありません。 どちらも簡単に元に戻すことができ、セキュリティは一切提供しません。エンコーディング形式であり、暗号操作ではないのです。

ユースケース

設定ファイルにバイナリの暗号鍵を格納する際に16進数とBase64のどちらを使うか選ぶ場面で、フットプリントが小さいBase64が好まれます。

試してみる — Base64 Encoder

フルツールを開く