Base64とHexの違い
どちらも同じバイト列に対するRFC 4648のテキストエンコーディングです――違いは算術と住み分けにあります。Hexはサイズを2倍にしますが、ニブル単位に整列し、パディング不要です。そのためチェックサム、MACアドレス、デバッグの領分です。Base64はデータを1/3増やす代わりに、大量輸送の領分を受け持ちます。MIME、JWT、data URI、クッキーです。
Base64とHexの違いとは
2つのエンコーディングは交換可能に見えます。どちらも任意のバイト列を印字可能なテキストに変え、どちらも可逆にデコードでき、どちらもRFC 4648に並んで定義されています。しかし競合関係というより、算術の異なる2つの綴り方です。16進数は1バイトに2文字を使い、base64は3バイトを4文字に詰め込みます。このページのその他のすべて――パディングから住み分けまで――は、この算術から派生しています。
数値で正確に言えば、16進数はbase16です――16種類の文字、1文字あたり4ビット――そのため8ビットのバイト1つは正確に2文字になり、ペイロードは100%増えます。Base64は64種類の文字、1文字あたり6ビットを使い、8と6の最小公倍数が24であることから、3バイトが4文字になります。オーバーヘッドは33%で、入力が3バイトの倍数でないときは常に=のパディングで切り上げられます。
このページは、この算術を意思決定に変えます。並べて比較する表、計算例つきのサイズ計算、それぞれのエンコーディングが慣例となった領域、そして厳格なデコーダーが拒否する落とし穴――パディング、アルファベットの変種、大文字小文字です。下のコンバーターはローカルで両者を切り替えます。アップロードされるものは何もありません。
自分のペイロードでサイズの違いを確かめるなら、Base64からHexへの変換ツールがローカルで再エンコードし、倍増した文字数を表示します。
転送のためにhex文字列をスリム化する場合も、同じ要領です。HexからBase64への変換ツールが3バイトずつ4文字に詰め込みます。処理は完全にブラウザ内で行われます。
同じバイト列、2つのアルファベット
どちらのエンコーディングも1つの問題を解決します。バイトは8ビットの値ですが、テキストで運ぶ経路――URL、ヘッダー、XML、JSON、メール――は印字可能なASCIIを最も好む、ということです。Hexは0-9とa-fの16文字を、base64はA-Z、a-z、0-9、+、/を使います。どちらも暗号化も圧縮もしません。仕様は公開され、鍵は不要で、即座に逆変換できます。base64文字列は輸送の安全であって、セキュリティではありません。
| 項目 | Base64 | 16進数 |
|---|---|---|
| アルファベット | 64文字:A-Z、a-z、0-9、+、/ | 16文字:0-9、a-f |
| 1文字あたりのビット数 | 6 | 4 |
| サイズのオーバーヘッド | +33%――3バイトごとに4文字 | +100%――1バイトごとに2文字 |
| パディング | =で出力を4の倍数に調整 | なし――1バイトは常にちょうど2文字 |
| 変種 | URLセーフ形式は+と/を-と_に置き換える | 慣例上、大文字小文字を区別しない |
| 定番の使用場所 | MIME、JWT、data: URI、クッキー | チェックサム、UUID、MACアドレス、hexダンプ |
| 標準 | RFC 4648 セクション4と5 | RFC 4648 セクション8 |
算術:1/3と2倍
Hexはニブル単位に整列します。バイトは2つの4ビットの半分に分かれ、それぞれが1文字として描画されるため、長さは予測可能です。nバイトの値は常に2n文字で、パディングも例外もありません。Base64はビットを6ビットの塊に組み替えます。24ビットはバイトの世界とbase64の世界が最初に整列する地点であり、3バイトが4文字になります。残りが1バイトなら==に、2バイトなら1つの=にパディングされます。
計算例の1組が比率を具体的にします。Hiのバイト列はhexでは48 69(4文字)、base64ではSGk=(これもパディング込みで4文字)です。実規模になると差が支配的になります。1メガバイトのデータは、パディング付きbase64では約1.33 MB、hexでは正確に2 MBです。大量輸送がbase64に標準化され、短い値はhexのまま残ったのはこのためです。
それぞれの棲み分け
Base64の領分は大量と輸送です。MIMEはメール添付に使い、HTTP Basic認証は資格情報をこれでエンコードし、JWTはヘッダー、ペイロード、署名をbase64urlにし、data: URIは画像やフォントをページやスタイルシートに直接埋め込み、クッキーはbase64url値を運びます――+と/はURLやヘッダーの中で問題を起こすためです。バイナリがテキスト専用のパイプを最小コストで生き延びなければならない場所では、どこでも答えはbase64です。
Hexの領分は小さな値と、人間が目で確認するものです。暗号学的ダイジェストは慣例でhex表示されます――SHA-256の出力、gitのコミット識別子――幅が固定で、パディングがなく、バイト単位に揃ったペアは、目視でも口頭でも比較が簡単だからです。MACアドレス、UUIDのテキスト形式、#RRGGBBのようなCSSの色はすべてhexです。hexエディタ、メモリダンプ、プロトコルデバッガがhexを使うのは、すべてのバイトが自己完結した単位として読めるからです。
落とし穴と、どちらを選ぶか
Base64の落とし穴はすべてアルファベットの中にあります。標準とURLセーフの変種は2文字違いで、決して混ぜてはいけません。パディングは厳格なデコーダーには必須なのに、JWTの慣例では剥ぎ取られます。出力は大文字小文字を区別します。そしてMIMEは76文字で行を折り返します。Hexの落とし穴は1つだけです。大文字小文字です。小文字が慣例で、大文字を使うツールもありますが、混在しても見た目の問題――どの厳格なデコーダーもどちらでも受け付けます。
つまり、ボリュームが問題になるか、プロトコルが要求するときはbase64――添付、トークン、埋め込みバイナリです。人間が比較、コピー、デバッグする短い値にはhex――ダイジェスト、識別子、色です。実際のシステムでは選択は絶えず入れ替わります。JWTはbase64urlで届き、そのSHA-256フィンガープリントはhexです。下のコンバーターが、この渡りをブラウザ内で処理します。
よくある質問
base64とhex、どちらがコンパクトですか?
Base64です。常に、そして正確に。Hexは1バイトに2文字書き、base64は3バイトに4文字書きます。同じ入力なら、base64の出力はhexの2/3の長さです。具体的には、1メガバイトのデータは、パディング付きbase64で約1.33 MB、hexでは正確に2 MBになります。
base64は暗号化ですか?何かを隠していますか?
いいえ――どちらのエンコーディングも秘密性を提供しません。どちらも鍵なしで、仕様が公開されており、誰でも即座に逆変換できます。パスワードのbase64文字列は、どこでもそのパスワードにデコードされます。両者が解決するのは輸送であって、機密性ではありません。テキスト専用のチャネルをバイナリデータが生き延びるための仕組みです。秘密性には暗号化が必要で、その後も暗号文が輸送のためにbase64エンコードされることはあります。
base64とhexの変換ツールはデータをアップロードしますか?
いいえ。エンコード、デコード、変換はすべてブラウザのタブの中で動作します。アップロードのエンドポイントはなく、サイトのContent-Security-Policyは自分自身へのネットワークリクエストしか許可しません。変換中にDevToolsのNetworkパネルを見てください。外向きのリクエストは一切見えません。うっかり貼り付けた秘密を含め、ペイロードがタブの外に出ることはありません。
ハッシュやチェックサムがhexで表示されるのはなぜですか?
機械的な都合で固まった慣習です。hex出力は幅が固定で、パディングが不要で、各バイトの2文字が揃うため、比較やdiffが視覚的に整列します。英数字だけのアルファベットは、コピペでもログでもCSVでも壊れません。opensslからgitまで、あらゆるツールがダイジェストをhexで印字します。人間が読み方を覚えたのはhexなのです。
base64urlとは何ですか?いつ必要になりますか?
RFC 4648セクション5のURLセーフ変種です。プラスとスラッシュがマイナスとアンダースコアに置き換わります。フォームエンコードでは+がスペースとして読まれ、/はパス区切りを壊すためです。JWT、クッキー、クエリパラメータがこれを使うのは、トークンがURLの中で無傷で生き延びるためです。デコーダーは両方のアルファベットを受け付けるべきで、厳格なものは混在を拒否します。
base64が=や==で終わることがあるのはなぜですか?
パディングです。Base64の出力は4文字の倍数でなければならず、入力が3バイトの倍数でないとき、1つか2つの=が最後のグループを埋めます。残りが1バイトなら==が付き、2バイトなら1つの=が付きます。Hexにパディングは不要です。1バイトあたり2文字は常に割り切れるからです。
ここで引用した規格はどこで読めますか?
- RFC 4648 — Base16・Base32・Base64のデータエンコーディング