コードベース全体にBase64文字列が散在しているのを見たことがあるでしょう — JWTトークン、
HTMLの<img>タグ、HTTP Authorizationヘッダー、またはファイルデータを含むJSONペイロードなど。
SGVsbG8sIFdvcmxkIQ==のように、意味不明に見えます。しかし、それらが存在する明確な理由があり、
一度理解すれば、Base64は謎めいたものではなく、あなたのツールボックスにおける本当に役立つツールになります。
Base64とは何か
Base64はバイナリ-テキスト変換スキームです。それだけです。 ヌル文字、制御コード、または0から255の任意の値を含む可能性のある任意のバイナリデータを取り込み、 64個の印刷可能な ASCII文字のみを使用して表現します。 結果は、破損したり誤解されたりすることなく、任意のテキストベースのチャネルを安全に通過できる文字列です。
正式な仕様はIETFが発行した RFC 4648に記載されています。 標準Base64とURLセーフバリアントの両方を定義しています。パディングルールやアルファベットの選択について 議論を解決する必要がある場合に備えてブックマークしておく価値があります。
Base64アルファベット
64文字のアルファベットは、大文字A–Z(26文字)、
小文字a–z(26文字)、数字0–9(10文字)、
そして2つの記号:+と/で構成されています。これでちょうど64文字になります —
これが名前の由来です。入力の長さが3の倍数でない場合、末尾のパディング文字として=記号が使用されます。
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/各文字はデータの正確に6ビットをエンコードします(2^6 = 64の可能な値)。これが エンコードの核心的なメカニズムであり、約33%のサイズオーバーヘッドの理由です。
エンコードの仕組み
アルゴリズムは3バイト → 4つのBase64文字のチャンクで動作します。 3バイト = 24ビット。その24ビットを4つの6ビットグループに分割し、各グループがBase64アルファベットの 1つの文字にマッピングされます。
Input: "Man"
Bytes: M=77 (01001101) a=97 (01100001) n=110 (01101110)
Bits: 010011 010110 000101 101110
Index: 19 22 5 46
Output: T W F u → "TWFu"入力が3で割り切れない場合、パディングが機能します。残り2バイトは
3つのBase64文字と1つの=になります。残り1バイトは2つのBase64文字
と==になります。パディングはデコーダーに末尾に実際に何バイトあるかを伝えるだけです —
それはデータ自体の一部ではありません。
JavaScriptでのエンコードとデコード
ブラウザは
btoa()
と
atob()
をグローバルとして公開しています。シンプルですが落とし穴があります:Latin-1文字(バイト値0〜255)のみを処理します。
マルチバイトのUnicode文字列を直接渡すとInvalidCharacterErrorが発生します。
// Basic browser encoding/decoding
const encoded = btoa('Hello, World!'); // "SGVsbG8sIFdvcmxkIQ=="
const decoded = atob('SGVsbG8sIFdvcmxkIQ=='); // "Hello, World!"
// Safe Unicode version — encode to UTF-8 first
function encodeUnicode(str) {
return btoa(
encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (_, hex) =>
String.fromCharCode(parseInt(hex, 16))
)
);
}
function decodeUnicode(str) {
return decodeURIComponent(
atob(str)
.split('')
.map(c => '%' + c.charCodeAt(0).toString(16).padStart(2, '0'))
.join('')
);
}
const emoji = encodeUnicode('Héllo wörld 🌍');
console.log(emoji); // "SMOpbGxvIHfDtnJsZCDwn4yN"
console.log(decodeUnicode(emoji)); // "Héllo wörld 🌍"Node.js — Bufferの使用
Node.jsでは、慣用的なアプローチは Buffer APIです。 これはUnicodeを正しく処理し、上記のブラウザの回避策よりもずっとクリーンです。
// Encoding
const encoded = Buffer.from('Hello, World!', 'utf8').toString('base64');
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="
// Decoding
const decoded = Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64').toString('utf8');
console.log(decoded); // "Hello, World!"
// Encoding a file to Base64 (e.g. to embed in a JSON payload)
const fs = require('fs');
function fileToBase64(filePath) {
const fileBuffer = fs.readFileSync(filePath);
return fileBuffer.toString('base64');
}
function base64ToFile(base64String, outputPath) {
const fileBuffer = Buffer.from(base64String, 'base64');
fs.writeFileSync(outputPath, fileBuffer);
}
const avatarBase64 = fileToBase64('./uploads/avatar.png');
const payload = {
userId: 'usr_8f3k2',
avatarData: avatarBase64,
mimeType: 'image/png'
};Python — base64モジュール
Pythonの標準ライブラリには、エンコード、デコード、URLセーフバリアントを処理する base64モジュール が含まれています。関数はbytesオブジェクトで動作するため、 通常は明示的な文字セットで文字列をエンコード/デコードします。
import base64
# Encoding a string
message = "Hello, World!"
encoded = base64.b64encode(message.encode("utf-8"))
print(encoded) # b'SGVsbG8sIFdvcmxkIQ=='
print(encoded.decode()) # 'SGVsbG8sIFdvcmxkIQ=='
# Decoding
decoded_bytes = base64.b64decode("SGVsbG8sIFdvcmxkIQ==")
print(decoded_bytes.decode("utf-8")) # 'Hello, World!'
# Encoding a file
with open("report.pdf", "rb") as f:
pdf_base64 = base64.b64encode(f.read()).decode("utf-8")
# Embedding it in a JSON-compatible structure
import json
payload = {
"filename": "report.pdf",
"content": pdf_base64,
"encoding": "base64"
}
print(json.dumps(payload, indent=2))URLセーフBase64
標準のBase64はURLで特殊文字である+と/を使用します。
標準のBase64文字列をクエリパラメータに入れると、最初にパーセントエンコードしない限り
微妙な破損が発生します。URLセーフBase64(
RFC 4648 §5でも定義)は
+を-に、/を_に置き換えることでこれを解決します。
パディング=記号はURLコンテキストでは完全に省略されることが多いです。
// Standard → URL-safe conversion in JavaScript
function toBase64Url(base64) {
return base64
.replace(/+/g, '-')
.replace(///g, '_')
.replace(/=+$/, ''); // strip padding
}
function fromBase64Url(base64url) {
// Restore padding
const padded = base64url + '=='.slice(0, (4 - (base64url.length % 4)) % 4);
return padded.replace(/-/g, '+').replace(/_/g, '/');
}
const standard = btoa('some binary data');
const urlSafe = toBase64Url(standard);
console.log(standard); // "c29tZSBiaW5hcnkAAGRhdGE="
console.log(urlSafe); // "c29tZSBiaW5hcnkAAGRhdGE" (safe for URLs)Pythonではbase64.urlsafe_b64encode()と
base64.urlsafe_b64decode()を使用してください — 自動的に置換を行います。
一般的な実際のユースケース
- HTML/CSSへの画像の埋め込み —
data:URIのようなsrc="data:image/png;base64,iVBORw0KGgo..."は別のHTTPリクエストを排除します。 小さなアイコンやスプライトには最適ですが、33%のサイズオーバーヘッドのため大きな画像には不向きです。 - JWTトークン — JSON Webトークンの ヘッダーとペイロードセクションはURLセーフBase64エンコードされたJSONオブジェクトです。JWTで見るドット区切りの3つの部分は Base64Url(ヘッダー).Base64Url(ペイロード).Base64Url(署名)です。
- HTTP基本認証 —
Authorization: Basic ...ヘッダーはユーザー名:パスワードをBase64としてエンコードします。 RFC 7617で定義されています。 注意:これはエンコードであり、暗号化ではありません — 常にHTTPSを使用してください。 - JSONへのバイナリデータの埋め込み — JSONにはバイナリ型がないため、APIを介して送信されるファイル、画像、 証明書は通常、文字列フィールドにBase64エンコードされます。このワークフローについては ファイルからBase64と画像からBase64 ツールを参照してください。
- メールの添付ファイル — MIME(メールの基礎フォーマット)はBase64を使用して バイナリの添付ファイルをエンコードし、テキストのみのメールリレーサーバーを通じた転送で生き残れるようにします。 Base64が解決するために設計された元の問題です。
- データベースへのバイナリデータの保存 — テキスト列またはJSONドキュメント内に小さなブロブ (証明書、サムネイル)を格納する必要がある場合、Base64が標準的な選択です。
Base64は暗号化ではない
これは常に人々を混乱させます — 特にコードレビュー時に。Base64は エンコードであり、暗号化ではありません。エンコードはデータの表現を変更する 可逆的な変換です。暗号化は秘密鍵を使用してデータをスクランブルし、 鍵を持つ人だけが逆にできるようにします。
誰でも数秒でBase64文字列をデコードできます —
Base64デコーダーに貼り付ければ完了です。パスワード、APIキー、
個人データなどの機密値を「隠す」ためにBase64を使用しないでください。機密性が必要な場合は、
実際の暗号化(AES、RSA、またはブラウザの
Web Crypto API、
またはPythonのcryptographyなどのライブラリ)を使用してください。
Base64を扱うためのツール
毎日Base64を扱う場合、迅速なツールを持つことで大きな違いが生まれます。 任意のテキスト文字列をエンコードするにはBase64エンコーダー、 Base64値をデコードして検査するにはBase64デコーダー、 APIペイロードやストレージ用にバイナリファイルを変換するにはファイルからBase64、 HTMLやCSSに直接画像を埋め込むためのデータURIを生成するには画像からBase64 を使用してください。
まとめ
Base64はテキストのみのチャネルを通じてバイナリデータを破損なく通過させるという 特定の問題を解決するために存在します。64文字のアルファベット(A–Z、a–z、0–9、+、/)を使用して、 入力の3バイトごとに4つの印刷可能なASCII文字にマッピングすることでこれを実現します。 結果はメール、HTTPヘッダー、JSONフィールド、およびURL(URLセーフバリアントで)に安全です。 トレードオフは固定された33%のサイズ増加です。暗号化でも圧縮でもありません — 透明で可逆的なエンコードです。これを内面化すると、いつそれを使うべきか、 いつ別のツールが適しているかをすぐに知ることができます。