レッスン 5
Base64 と Hex の比較
16 進エンコードより Base64 を選ぶとき。
16 進数(hex)は各ニブル(4 ビット)を 16 個の ASCII 記号 0–9A–F の 1 つに展開します。Base64 は出力文字あたりより多くのビット — 4 ではなく 6 — を詰めるため、payload は文字数では短くなります(圧縮層後のバイトサイズが常に短いとは限りません)。
拡張率(ざっくり直感)
| エンコード | 出力記号あたりのビット | アルファベットサイズ |
|---|---|---|
| Hex | 4 | 16 |
| Base64 | 6 | 64 |
フレーミングを無視すると、Base64 は概ね 3 生バイトあたり約 4 文字。Hex は1 バイトあたり 2 文字。Base64 の約 33% オーバーヘッドは、hex が無条件に可視長を 2 倍にするまで悪く聞こえます。
具体感: 16 生バイト ⇒ 32 hex 桁 vs おおよそ 22 Base64 文字(整列とパディング末尾次第)。
hex が輝くとき
次の場合は hex を優先:
- 人間が目視 diff するフィンガープリント(ハッシュは hex 表示が多い)
- 印字安全な狭い文字セットだけど 1 バイト = 2 文字の単純対応が欲しい
- パディングのメンタル負荷を避けたいクイックスクリプト
- 大文字小文字を区別しない辞書順が一律必要(hex 大文字化で比較を標準化)
Git のハッシュ、ダウンロードページの SHA-256 — hex 優位は暗号的必然ではなく人間工学です。
Base64 が輝くとき
次の場合は Base64 を優先:
- バイナリを歴史的 MIME / JSON 風テキストエンベロープに素早く埋め込む
- チャネルが奇数幅を食う改行非依存パーサーの曖昧さを避けたい(折り返しには依然注意)
- 長い hex ブロブより区切り文字が少ない(主観的可読性トレードオフ)
- ライブラリエコシステムが Base64 ラッパーで標準化済み(JWT、PEM 内部 payload)
どちらもエントロピーを圧縮しません。選択は輸送の人間工学です。
混在パイプライン
危険パターン: UI で SHA-256 を hex 表示 → 開発者がASCII hex 文字列を Base64 エンコード(生 digest バイトではない)→ チェックサム地獄。明確に: digest オブジェクト vs 可印刷表現 vs ワイヤーエンコード層。
同様、二重適用(hex してから Base64)は、意図的プロトコルステップに結びつかない限り、ほとんど助けになりません。
混乱例(概念的)
digest_bytes = 暗号出力(SHA-256 典型 32 不透明バイト)
hex_string = digest_bytes の人間向けビュー('a3f...')
base64_digest = 同じバイトの別ビュー(別アルファベット)
形式変換は同一オクテットに unpack する必要があります。
パフォーマンス
典型的サイズ(数 MB 未満)では現代 CPU で計算コストは無視できます。シリアライズ選択はマイクロベンチマークより相互運用 + 明確さに従うべきです。
要点
Hex は規則的(2 文字/バイト); Base64 は印字 ASCII 中心スタックでより高密度。プロトコルが意図する生バイトをエンコードし — 誤ったテキスト中間物ではなく — バリデーターが期待する正規文字列形式を文書化してください。