Base64 と URL エンコードは、どちらも「データをテキストとして安全に送る」ための道具なので混同しがちです。でも解決する問題は異なります。違いを見ていきましょう。
同じ文字列、2 つのエンコード、並べて。
台北 101を両方のツールに入れました。Base64 は5Y+w5YyXIDEwMQ==、URL エンコーダーは%E5%8F%B0%E5%8C%97%20101を返します。出発点は同じ 10 バイトの UTF-8 ですが、そこから完全に分かれます。Base64 はすべてのバイトを 64 文字のアルファベットで表し直し、4 の倍数までパディングします(だから==)。パーセントエンコードは1・0・1のような安全な文字をそのまま残し、残りだけを escape します。Base64 が一律に 3 分の 1 増え、URL エンコードが必要な分だけ増えるのはこのためです。
Base64:バイナリ → テキスト
Base64 はあらゆるバイナリデータ(画像・ファイル・生バイト)を、ASCII の英数字と +・/・= に変えます。データは約 33% 大きくなり、暗号化ではありません——誰でもデコードできます。テキストしか通せない経路でバイナリを運ぶときに使います。
- 画像を
data:URI として HTML/CSS に埋め込む - メール添付(MIME)
- 小さなバイナリを JSON やトークンに入れる
詳しくは Base64 は暗号化?(ネタバレ:違います)。
URL エンコード:URL に安全に入れるテキスト
URL エンコード(別名パーセントエンコード)は、URL で特別な意味を持つ、または使えない文字を %XX に置き換えます——スペースは %20、& は %26 など。次の場所にテキストを入れるときに使います。
- クエリ文字列(
?q=hello%20world) - パスの一部
- フォーム送信
詳細は URL エンコードガイド を。
違いを一目で
- 目的:Base64 = バイナリをテキストで運ぶ · URL エンコード = テキストを URL で安全にする。
- 出力:Base64 = A–Z a–z 0–9 + / = · URL エンコード = 元のテキスト +
%XXエスケープ。 - サイズ:Base64 ≈ +33% · URL エンコードはエスケープされた文字だけ増える。
2 つの方式が最も食い違うのは非 ASCII の入力で、その差は測れます。台北 は UTF-8 で 6 バイト。Base64 はこの 6 バイトを 5Y+w5YyX —— 8 文字にします。パーセントエンコーディングは同じ 6 バイトを %E5%8F%B0%E5%8C%97 —— 18 文字にします。1 バイトあたり 3 文字、% と 16 進 2 桁だからです。Base64 のほうが圧倒的に短い。ただし URL 欄では読めません。だから URL はもう一方を使います。
両者はよく組み合わさる
Base64 文字列は +・/・= を含むことがあり、URL では安全ではありません——そこで Base64 を URL に入れるなら、URL エンコードするか、Base64URL(- と _ を使う URL 安全版)を使います。
両方試す(端末内)
- Base64 エンコード/デコード——バイナリ/テキスト ⇄ Base64。
- URL エンコード/デコード——テキストを URL 用にパーセントエンコード。
目安:バイナリをテキストで運ぶなら Base64、テキストをリンクに安全に入れるなら URL エンコード。
実際の例
テキスト a b&c を見てみましょう。2つのエンコードはまったく別の扱いをします。
入力: a b&c
URL エンコード: a%20b%26c
Base64: YSBiJmM=
URL エンコードは英字にはふれず、スペースと & だけをエスケープするので、結果はまだ読めます。Base64 はすべてのバイトを独自のアルファベットに書き換え(3 バイトを 4 文字に)、出力は入力とまるで似ていません——その代わり、安全な文字が少ししか通らない経路でも生き残れます。仕事が違えば、出力も違うのです。
パディングは最も恣意的に見える部分ですが、入力の長さを 4 通り並べれば恣意性は消えます。Base64 は 3 バイトを読んで 4 文字を出します。最後のグループが 3 バイトに足りないとき、その不足分を記録するのが = です。以下の各行は私たちの Base64 エンコーダーの出力です。
| 入力 | Base64 | パディング |
|---|---|---|
a | YQ== | == |
ab | YWI= | = |
abc | YWJj | — |
abcd | YWJjZA== | == |
hello | aGVsbG8= | = |
台北 | 5Y+w5YyX | — |
🎉 | 8J+OiQ== | == |
よくある誤用
- Base64 でデータを「隠す」:一手で戻せるので何も守れません——鍵ではなく封筒だと考えてください。Base64 は暗号化? を参照。
- URL 全体を URL エンコードする:エンコードするのは一部分(クエリ値やパスの一部)であって、アドレス全体ではありません。さもないと
https://がhttps%3A%2F%2Fになりリンクが壊れます。 - 二重エンコード:すでにエンコードした値をもう一度エンコードすると
%2520になります(%自体がエスケープされた形)。スペースが%20ではなく%2520で届いたら、二度エンコードされた証拠です。 - Base64 の
+と/を忘れる:素の Base64 は URL セーフではありません。URL に入れるなら Base64URL を使うか、文字列を URL エンコードします。
Base64 の最も多い誤用は「隠す手段」として扱うことで、具体的な値 1 つがその価値を示します。admin:password は YWRtaW46cGFzc3dvcmQ= に符号化され、それは HTTP Basic 認証がヘッダーに入れるものそのままです。{"role":"admin"} は eyJyb2xlIjoiYWRtaW4ifQ== になります。どちらも鍵なしで復号できます。パーセントエンコーディングが隠蔽と誤解されないのは読めるままだからで、Base64 が誤解されるのはまさに読めないからです。どちらも安全対策ではありません。一方がそれらしく見えるだけです。
それぞれの出番
- Base64 は、バイナリをテキストに載せる場面で登場します:
data:URI、メールの MIME パート、JWT の各セグメント、JSON に詰め込むバイナリ項目など。 - URL エンコード は、テキストを URL に載せる場面で登場します:クエリ文字列、フォーム送信(
application/x-www-form-urlencoded)、スペースや非 ASCII を含むパスの一部など。
よくある質問
URL エンコードの代わりに Base64 を使える?
いいえ——両者は交換できません。Base64 はバイナリをテキストセーフに、URL エンコードはテキストを URL セーフにします。素の Base64 を URL に入れると、+・/・= のせいで壊れることがあります。
Base64 の末尾が = なのはなぜ?
出力の長さを 4 の倍数にそろえるためのパディングです。正常で、URL セーフな一部の変種では省かれます。
どちらかでデータは安全になる?
なりません。エンコードは形式の話で、秘密の話ではありません——誰でも元に戻せます。機密性には暗号化を、改ざん検知にはハッシュか署名を使います。