メインコンテンツへスキップ

← ブログ一覧へ

Base64 と URL エンコードの違いは?

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、テキストをリンクに安全に入れるなら 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パディング
aYQ====
abYWI==
abcYWJj—
abcdYWJjZA====
helloaGVsbG8==
台北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 セーフな一部の変種では省かれます。

どちらかでデータは安全になる?

なりません。エンコードは形式の話で、秘密の話ではありません——誰でも元に戻せます。機密性には暗号化を、改ざん検知にはハッシュか署名を使います。