Base64 エンコーディングとは何か、いつ使うか
API、メールシステム、Web開発で作業しているなら、認識していなくてもBase64に遭遇しています。メール添付の冒頭で意味不明に見える長い文字と数字の文字列、CSSのdata: URL、JWTトークンの中央セグメントなど、それがBase64です。インターネット配管の最も古く、最も静かに荷重を担っている一片であり、使うほぼすべてのソフトウェアがどこかでそれに依存しています。
Base64の簡単な歴史
Base64は「radix-64」または「印刷可能エンコーディング」と呼ばれるファミリーの一部で、その仕事は、テキストベースのシステムが変更せずに通すことが保証されている小さな文字アルファベットのみを使って、任意のバイトを表現することです。最も古く広く使われたメンバーはuuencodeで、1980年頃にUC Berkeleyの Mary Ann Hortonによって書かれ、Usenetとメールでバイナリファイルを送るためのものでした。これらのシステムは7ビットASCIIを超えるものを壊していました。
Base64アルファベット自体は、署名と暗号化メールの初期の試みであるPrivacy-Enhanced Mail(PEM)のために、1987年のRFC 989で最初に標準化されました。PEMは消滅しましたが、そのエンコーディングスキームは生き残り、1993年のRFC 1421、その後1993年のMIME仕様(RFC 1521と1522、1996年にRFC 2045から2049に改訂)で正典化されました。MIMEはBase64をメールにバイナリファイルを添付するデフォルトの方法にし、そこからエンコーディングはインターネット上のほぼすべてのテキストのみのトランスポートに広がりました。
2006年、IETFは散らばったBase64の定義をRFC 4648に統合し、これは1つの文書でBase64、Base32、Base16を定義します。RFC 4648はセクション5でURL安全バリアントも定義し、2つの非URLフレンドリーな文字(+と/)を-と_に交換しました。JSON Web Tokens(2015年のRFC 7519)はパディングを取り除いたURL安全Base64を標準化しました。今日、すべてのメール添付、すべてのPEMエンコード証明書、すべてのdata: URL、すべてのJWT、すべてのマルチパートアップロード境界がBase64に依存します。
Base64の動作: 数学
Base64は3つの入力バイト(24ビット)を取り、64シンボルアルファベットを使って4つの出力文字(各6ビット)として書き直します。マッピングは固定です:
| インデックス範囲 | 文字 |
|---|---|
| 0から25 | A-Z |
| 26から51 | a-z |
| 52から61 | 0-9 |
| 62 | +(標準)または-(URL安全) |
| 63 | /(標準)または_(URL安全) |
つまりHelloはこうなります:
- ASCIIバイト:
0x48 0x65 0x6C 0x6C 0x6F(5バイト) - バイナリ:
01001000 01100101 01101100 01101100 01101111 - 6ビットチャンクに再グループ化:
010010 000110 010101 101100 011011 000110 1111 - 最後のチャンクは短く、ゼロビットでパディング:
010010 000110 010101 101100 011011 000110 111100 - ルックアップ:
S G V s b G 8(6ビット6グループ = 36ビットからわずか7文字、欠けた4にパディング) - パディング: 4つの出力文字の倍数に丸めるために
=を追加:SGVsbG8=
出力はつねに4文字の倍数です。入力長を3で割った余りが1なら2つの=パディング文字が、2なら1つの=が、0ならパディングなしになります。パディングはときに取り除かれ(特にJWTとURLフラグメントで)、デコーダーはそれを許容することが期待されます。
33%のサイズオーバーヘッドはこの3対4の拡張から来ます。入力の3バイトごとに4文字の出力になり、3分の1の増加です。アルファベットを変えずに減らす方法はありません(Base85 / Ascii85は85の印刷可能文字を使って25%しか拡張しませんが、より複雑なエンコーダーが代償です)。
一般的なユースケース
メール添付: サーバー間でメールの95%を運ぶプロトコルであるSMTPは、1982年(RFC 821)に7ビットASCII用に設計されました。送るすべてのバイナリ添付(画像、PDF、ZIP)は、メールクライアントによって送信前にBase64エンコードされ、受信者のクライアントによってデコードされます。メール内のMIMEヘッダーは、どの部分がBase64でどれがプレーンテキストかを受信者に伝えます。
HTMLとCSSのData URL: data:image/png;base64,iVBORw0KGgo...のようなURLは、文書にバイナリファイルを直接埋め込みます。1から2 KB未満の小さなアイコンに有用で、節約されたHTTPリクエストが33%のサイズオーバーヘッドとキャッシュの損失を上回ります。
APIペイロード: JSONやXML APIがバイナリ値(ファイルアップロード、署名、プロフィール写真)を受け入れる必要があるとき、標準パターンはバイトをBase64エンコードして文字列フィールドとして出荷することです。受信側はサーバー側でデコードします。OpenAIの画像入力、Stripeのファイルアップロード受信、ほとんどのクラウド関数のバイナリ入力受け入れがこの方法です。
HTTP Basic認証: Authorization: Basic <token>ヘッダーはBase64エンコードされたusername:passwordペアを運びます(RFC 7617)。これはエンコーディングであり暗号化ではありません。ヘッダーを見た誰もがパスワードを見ます。Basic認証はそのためHTTPSを必要とします。
証明書と鍵: PEMファイル(-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----)は、DERエンコードされたASN.1バイトのBase64エンコードされたブロブをラップします。すべてのTLS証明書、すべてのSSH鍵ファイル、すべてのコード署名証明書は、PEMエンベロープ内のBase64です。
JWTトークン: JWTはドットで区切られた3つのURL安全Base64セグメントです: <ヘッダー>.<ペイロード>.<署名>。Base64エンコーディングにより、JWTはヘッダー、URL、クッキーで安全に移動できます。
エンコードとデコードの手順
- エンコードかデコードを選ぶ: 変換方向を選択します。
- テキストを貼り付けるかファイルをアップロード: テキストを直接入力するか、ファイルをドラッグ&ドロップ(ブラウザサイドエンコードで最大5 MB)。
- バリアントを選ぶ: メールと証明書には標準Base64、JWTとURLフラグメントにはURL安全。ツールは標準にデフォルト設定されています。
- 結果をコピー: 出力は即座に更新されます。クリップボードにコピーするか、長い出力にはダウンロードボタンを使います。
Base64のバリアント
特定の状況のためにいくつかのBase64ライクなエンコーディングが存在します:
| バリアント | 違い | 使われる場所 |
|---|---|---|
| 標準(RFC 4648 §4) | A-Z、a-z、0-9、+、/、=パディング | メール(MIME)、PEM、汎用バイナリからテキスト |
| URL安全(RFC 4648 §5) | +が-に、/が_に | JWT、URLフラグメント、ファイル名 |
| MIME(RFC 2045) | 76文字ごとに改行 | メール本文、メールヘッダー(=?utf-8?B?...?=付き) |
| crypt(3) / htpasswd | 異なるアルファベット(./0-9A-Za-z) | 古いUnixパスワードハッシュ(DESベース) |
| Base64Urlノーパディング | 末尾の=なしのURL安全 | JWT(RFC 7515による) |
| Base32(RFC 4648 §6) | 32文字アルファベット、大文字小文字非区別 | TOTPシークレット、Onionアドレス |
| Base58 | 58文字アルファベット(0、O、I、lなし) | Bitcoinアドレス、IPFS CID |
| Ascii85 / Base85 | 85文字アルファベット、25%オーバーヘッド | PDF、PostScript |
ほとんどの場合、標準またはURL安全Base64が欲しいものです。他は特定のプロトコルで登場します。
Base64を使うとき
次の場合に使ってください:
- 小さな画像(5 KB未満)をHTMLまたはCSSに直接埋め込み、1つのHTTPリクエストを節約する必要があるとき。
- APIがJSONまたはXMLペイロードでテキスト文字列としてバイナリデータを必要とするとき。
- テキストのみをサポートするシステム(メール、ログエントリ、クエリパラメーター)を通してバイナリデータを渡しているとき。
- JWT、証明書、鍵、または任意の構造化されたバイナリブロブをエンコードしているとき。
- 任意の言語がデコードできる決定論的で自己完結型の文字列表現が必要なとき。
次の場合は使わないでください:
- ファイルが大きい。Base64は33%のオーバーヘッドを加え、別のリソースとしてのブラウザキャッシュを防ぎ、ブロブ全体をページパーサーに通します。
- セキュリティが必要なとき。Base64は暗号化ではなく、自明に可逆です。
- ファイルを通常通り提供できるとき。プレーンな
<img src="photo.jpg">は、数KBを超えるものについてBase64データURLよりも効率的です。 - コンパクトな表現が必要なとき。サイズが重要でないなら、Hexがよりシンプルです。重要なら、Base85がより密です。
よくある落とし穴
- エンコーディングと暗号化の混同: Base64は誰でもミリ秒で可逆です。「秘密」をBase64に通すことは、肩越し盗み見以外からは何も保護しません。
- 33%のサイズペナルティ: 1 MBの画像は1.33 MBの文字列になり、インラインデータURLは別のキャッシュなしに、毎回親HTMLとともにダウンロードされます。
- MIME Base64の改行: Base64のMIMEバリアントは76文字ごとに
\r\nを挿入します。MIME Base64をJSON値やURLに貼り付けると失敗します。まず改行を取り除いてください。 - JWTでのパディング取り除き: JWTは
=パディングを取り除いたURL安全Base64を使います。パディングを厳密に要求するライブラリは有効なJWTを拒否します。パディングを生成しないライブラリは、他のライブラリが拒否するトークンを作成します。RFC 7515はJWS標準に「パディングなし」を義務付けます。 - URL安全と標準の混同: 標準デコーダーでURL安全文字列をデコードすると
-と_文字で失敗します。URL安全デコーダーで標準文字列をデコードすると+と/で失敗します。 - Unicode入力の扱い: Base64は文字ではなくバイト上で動作します。UTF-8絵文字の文字列をBase64エンコードする場合、まずバイトエンコーディング(ほぼ常にUTF-8)を決める必要があります。異なるランタイムは異なるデフォルトを持ちます。明示的に指定してください。
- ストリーミング部分デコーダー: 正しく実装されたBase64ストリームデコーダーは、3つの出力バイトを生成する前に4つの入力文字のグループを待ちます。一度に1文字をデコードする素朴な実装はゴミを生成します。
- 末尾の空白とBOM: 一部のテキストエディタは、ファイルを保存するときに改行やUTF-8バイトオーダーマークを追加します。その余分なバイトはBase64出力を変えます。予期しない不一致が見えたら、エンコード結果を上流ソースと差分してください。
- URLでスペースとして解釈される
+: 標準Base64の+は、URLパーサーによってパーセントデコードされるとスペースになります。これがまさにURL安全Base64が存在する理由です。
代替と隣接エンコーディング
Base64はデフォルトであって唯一の選択肢ではありません。正しい選択はチャネルとサイズ予算に依存します。
| エンコーディング | オーバーヘッド | 強み | 最適な用途 |
|---|---|---|---|
| Hex(Base16) | 100% | 読みやすい、各バイトが2文字 | デバッグ出力、短い識別子、カラーコード |
| Base32(RFC 4648) | 60% | 大文字小文字非区別、似た文字なし | TOTPシークレット、Onionアドレス、音声口述 |
| Base64標準 | 33% | 普遍的、すべての言語が持つ | メール、PEM、汎用トランスポート |
| Base64 URL安全 | 33% | URLとファイル名安全 | JWT、URLフラグメント |
| Base58 | 約37% | 0/O/I/l混同なし、特殊文字なし | Bitcoinアドレス、IPFS CID |
| Ascii85 / Base85 | 25% | Base64より密 | PDF、PostScript |
| Base91 | 約22% | さらに密、より複雑 | まれ、ニッチな圧縮文脈 |
| マルチパートアップロード | 0% | HTTPでのネイティブバイナリトランスポート | ファイルアップロード(ブラウザがこれを行う) |
| gzip + Base64 | 変動 | 生のBase64より小さいことがある | 事前圧縮されたペイロード |
ほとんどの日常作業では、答えはBase64(標準またはURL安全)です。HTTPでのバイナリファイルアップロードでは、正しい答えは通常、まったくエンコードしないmultipart/form-dataです。
プライバシーとエンコーダー
Base64エンコーダーとデコーダーは完全にブラウザ内で動作します。入力したテキストやファイルはデバイス上のJavaScriptで処理され、結果はページにレンダリングされ、何もサーバーに送信されません。ロギングなし、移動後の保存なし、コンテンツを見る分析タグなし。Base64エンコードするかもしれないもの(PEM証明書、秘密鍵、本番システムからのJWTペイロード、実際の顧客データを含むAPIリクエストの下書き)には、そのローカル専用フローが正しいデフォルトです。ツール全体は、ページを一度読み込めばオフラインで実行でき、ネットワークを切って同じ入力を再エンコードして検証できます。
よくある質問
Base64 はデータを暗号化しますか?
いいえ。Base64 はエンコーディングであって暗号化ではありません。誰でも Base64 文字列をデコードできるため、セキュリティはありません。データを保護したいなら、本物の暗号化(AES、RSA など)を使ってください。
なぜ Base64 でファイルが大きくなるのですか?
Base64 エンコーディングはデータサイズを約 33 % 増やします。3 バイトのバイナリが 4 文字の Base64 になります。このオーバーヘッドは、バイナリをテキストとして安全に転送できるための代償です。
テキストだけでなくファイルもエンコードできますか?
はい。任意のファイル(画像、PDF、音声)を Base64 にエンコードできます。データ URL として小さな画像を HTML や CSS に直接埋め込むのによく使われます。
Base64 を使うべきでないのはいつですか?
大きなファイルには使わないでください。1 MB の画像は Base64 テキストにすると 1.33 MB になり、ブラウザは別途キャッシュできません。数 KB を超えるなら、ファイルを普通に配信するほうが効率的です。
What is the difference between standard Base64 and URL-safe Base64?
Standard Base64 (RFC 4648 section 4) uses the characters A-Z, a-z, 0-9, +, / with = padding. URL-safe Base64 (RFC 4648 section 5) swaps + for - and / for _ so the string is safe to drop into a URL or a filename without percent-encoding. JWT tokens use the URL-safe variant.
Why does Base64 sometimes have one or two = signs at the end?
The = is padding. Base64 encodes input in 3-byte groups; if the input length is not a multiple of 3, the last group is padded with zero bits and one or two = characters mark the missing bytes. One = means one missing byte, two = means two missing bytes.