Python Base64 エンコード完全ガイド

·Backend Developer·レビュー担当Priya Sharma·公開日

無料の Base64エンコーダー をブラウザで直接使用 — インストール不要。

Base64エンコーダー をオンラインで試す →

HTTP Basic Auth ヘッダに認証情報を渡したり、API レスポンスにバイナリアセットを埋め込んだり、TLS 証明書を環境変数に保存したりする Python サービスを構築する際、base64 エンコードの Python コードを定期的に書くことになります。Python は base64 モジュールを標準ライブラリに含んでいるため pip インストールは不要ですが、bytes と string の違い、そして b64encode urlsafe_b64encode encodebytes の差異は、思った以上に多くの開発者をつまずかせます。コードを書かずに素早くエンコードするには、 ToolDeck の Base64 Encoder がブラウザ上で即座に処理します。本ガイドでは、完全な stdlib API、JWT 向け URL セーフエンコード、ファイルと API レスポンスのシナリオ、CLI のショートカット、高性能な代替手段、そしてコードレビューで最もよく見かける 4 つのミスをカバーします。

  • base64.b64encode() は str ではなく bytes を受け取る — 渡す前に入力文字列に対して .encode("utf-8") を呼び出すこと
  • 戻り値も bytes — JSON や HTTP ヘッダに埋め込める通常の str を得るには .decode("utf-8") または .decode("ascii") を呼び出す
  • base64.urlsafe_b64encode() は + を - に、/ を _ に置き換えるが = パディングは残る — JWT セグメントには手動で .rstrip("=") を呼び出すこと
  • base64.encodebytes() は76文字ごとに \n を挿入する(MIME 形式)— data URI・JSON フィールド・環境変数には絶対に使わないこと
  • pybase64(C 拡張、stdlib と互換 API)は stdlib より 2〜10 倍高速 — 大きなペイロードを処理する高スループットサービスに有効

Base64 エンコードとは?

Base64 は任意のバイナリデータを、64 個の印刷可能な ASCII 文字(A–Z、a–z、0–9、 + /)で構成された文字列に変換します。入力 3 バイトがちょうど 4 つの Base64 文字にマップされます。入力の長さが 3 の倍数でない場合、1 つまたは 2 つの = パディング文字が付加されます。エンコード後の出力は元のデータより常に約 33% 大きくなります。

Base64 は暗号化ではありません——機密性はまったく提供しません。その目的は転送の安全性です。多くのプロトコルやストレージシステムは 7 ビット ASCII テキスト向けに設計されており、任意のバイナリバイトを安全に扱えません。Base64 はそのギャップを埋めます。Python での一般的なユースケースには、HTTP Basic Auth ヘッダ、HTML や CSS に画像をインライン化するための data URI、JWT トークンセグメント、メールの MIME 添付ファイル、環境変数や JSON API を通じたバイナリブロブの受け渡しなどがあります。

Before · text
After · text
deploy-svc:sk-prod-9f2a1c3e8b4d
ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==

base64.b64encode() — 標準エンコードガイドと例

base64.b64encode(s, altchars=None) は Python の stdlib における主要なエンコード関数です。すべての Python インストールに含まれる base64 モジュールに属しています。この関数は bytes オブジェクトを受け取り、ASCII Base64 表現を含む bytes オブジェクトを返します。本ガイドは Python 3.x(3.6+)を前提としています。

最小動作例

Python 3.6+
import base64

# HTTP Basic Auth ヘッダ用に API 認証情報ペアをエンコード
service_id = "deploy-svc"
api_key    = "sk-prod-9f2a1c3e8b4d"

credential_bytes   = f"{service_id}:{api_key}".encode("utf-8")
encoded_bytes      = base64.b64encode(credential_bytes)
encoded_str        = encoded_bytes.decode("ascii")  # bytes → str

print(encoded_str)
# ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==

import urllib.request

req = urllib.request.Request("https://api.internal/v1/deployments")
req.add_header("Authorization", f"Basic {encoded_str}")
# ヘッダ値: Basic ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==

応用例 — sort_keys、ネストオブジェクト、ラウンドトリップデコード

Python 3.6+
import base64
import json

# 構造化サーバー設定を環境変数用にエンコード
server_config = {
    "host":           "db-primary.eu-west-1.internal",
    "port":           5432,
    "database":       "analytics_prod",
    "max_connections": 150,
    "ssl": {
        "mode":          "verify-full",
        "cert_path":     "/etc/ssl/certs/db-client.crt",
        "reject_self_signed": True,
    },
}

config_json    = json.dumps(server_config, sort_keys=True)
encoded_bytes  = base64.b64encode(config_json.encode("utf-8"))
encoded_str    = encoded_bytes.decode("ascii")

print(encoded_str[:60] + "...")
# eyJkYXRhYmFzZSI6ICJhbmFseXRpY3NfcHJvZCIsICJob3N0IjogImRi...

# デコードしてラウンドトリップを検証
decoded_json   = base64.b64decode(encoded_str).decode("utf-8")
restored       = json.loads(decoded_json)

print(restored["host"])            # db-primary.eu-west-1.internal
print(restored["ssl"]["mode"])     # verify-full
注意:b64decode() はデフォルトでは寛容——空白や改行を含む無効な文字を黙って無視します。 validate=True を渡すと、Base64 以外の文字があった場合に binascii.Error が発生します。外部システムからの信頼できない入力をデコードする際に使用してください。

Python で非 ASCII・Unicode 文字列をエンコードする

Python 3 の文字列はデフォルトで Unicode です。 base64 モジュールは str ではなく bytes を操作します——そのため渡す前に文字列を bytes にエンコードする必要があります。エンコードの選択は重要です。UTF-8 はすべての Unicode コードポイントを処理でき、ほぼすべてのユースケースに適しています。

Python 3.6+
import base64

# 多言語コンテンツのエンコード — 国際的なプラットフォームのユーザー表示名
user_names = [
    "田中太郎",              # 日本語 — ひらがな・漢字は UTF-8 で 3 バイト
    "山田花子",              # 日本語 — ひらがな・漢字は UTF-8 で 3 バイト
    "Мария Соколова",      # キリル文字 — U+041C 以上
    "Carlos Mendoza",      # ASCII — 1 文字 1 バイト
]

for name in user_names:
    encoded = base64.b64encode(name.encode("utf-8")).decode("ascii")
    decoded = base64.b64decode(encoded).decode("utf-8")

    print(f"元の値    : {name}")
    print(f"エンコード: {encoded}")
    print(f"ラウンド  : {decoded}")
    print(f"一致      : {name == decoded}")
    print()

# 元の値    : Мария Соколова
# エンコード: 0JzQsNGA0LjRjyDQodC+0LrQvtC70L7QstCw
# ラウンド  : Мария Соколова
# 一致      : True
注意:特定の文字列のエンコードが正しいか確認したい場合は、Base64 出力を ToolDeck の Base64 Encoder に直接貼り付けてください——リアルタイムでデコードし、正確な UTF-8 バイト表現を表示します。ペイロード文字列内のキリル文字、CJK 文字、絵文字のデバッグに役立ちます。

base64 モジュール — 関数リファレンス

base64 モジュールはいくつかのエンコード関数を提供しています。実際に使用するものの完全なリファレンスを以下に示します:

関数入力戻り値説明
b64encode(s, altchars=None)bytesbytes標準 Base64(RFC 4648 §4)。altchars で + と / を 2 つのカスタムバイトに置き換えられる。
b64decode(s, altchars=None, validate=False)bytes | strbytes標準 Base64 をデコード。validate=True で無効な入力文字があると binascii.Error を発生させる。
urlsafe_b64encode(s)bytesbytesURL セーフ Base64(RFC 4648 §5)。+ と / の代わりに - と _ を使用。= パディングを保持。
urlsafe_b64decode(s)bytes | strbytesURL セーフ Base64 をデコード。パディングあり・なしの両方の入力を受け付ける。
encodebytes(s)bytesbytesMIME Base64:76 文字ごとに \n を挿入し末尾にも \n を追加。メール/MIME 専用。
decodebytes(s)bytesbytesMIME Base64 をデコード。空白や埋め込まれた改行を無視する。
b16encode(s)bytesbytes16 進数エンコード(Base16)。各バイトが 2 つの大文字 16 進文字になる。パディングなし。
b32encode(s)bytesbytesBase32 エンコード。A–Z と 2–7 を使用。Base64 より出力が大きい。TOTP シークレットに使用。

b64encode altchars パラメータは、 + / を置き換える 2 バイトのオブジェクトを受け取ります。 altchars=b'-_' を渡すと urlsafe_b64encode と同一の出力が得られますが、パディングを個別に制御できます。

URL セーフ Base64 — JWT とクエリパラメータのための urlsafe_b64encode()

標準 Base64 は + / を使いますが、これらは両方とも URL の予約文字です。クエリ文字列中の + はスペースとしてデコードされ、 / はパス区切り文字です。エンコードされた値が URL、ファイル名、クッキーに現れる場合は URL セーフバリアントが必要です。 urlsafe_b64encode() + - に、 / _ に置き換えます。

JWT は 3 つのセグメント(ヘッダ、ペイロード、署名)すべてにパディングなしの URL セーフ Base64 を使用します。パディングは手動で除去する必要があります——Python の stdlib はこれを保持します。

JWT ペイロードセグメントのエンコード

Python 3.6+
import base64
import json

def encode_jwt_segment(data: dict) -> str:
    """dict をパディングなしの URL セーフ Base64 文字列にエンコード(JWT 形式)。"""
    json_bytes = json.dumps(data, separators=(",", ":")).encode("utf-8")
    return base64.urlsafe_b64encode(json_bytes).rstrip(b"=").decode("ascii")

def decode_jwt_segment(segment: str) -> dict:
    """URL セーフ Base64 の JWT セグメントをデコード(欠落パディングを処理)。"""
    # パディングを補完:Base64 は長さが 4 の倍数である必要がある
    padding  = 4 - len(segment) % 4
    padded   = segment + ("=" * (padding % 4))
    raw      = base64.urlsafe_b64decode(padded)
    return json.loads(raw)

# JWT ヘッダとペイロードを構築
header  = {"alg": "HS256", "typ": "JWT"}
payload = {
    "sub":       "usr_7c3a9f1b2d",
    "workspace": "ws_eu-west-1-prod",
    "role":      "data-engineer",
    "iat":       1741824000,
    "exp":       1741910400,
}

header_segment  = encode_jwt_segment(header)
payload_segment = encode_jwt_segment(payload)

print(header_segment)
# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

print(payload_segment)
# eyJzdWIiOiJ1c3JfN2MzYTlmMWIyZCIsIndvcmtzcGFjZSI6IndzX2...

# ラウンドトリップを検証
restored = decode_jwt_segment(payload_segment)
print(restored["role"])  # data-engineer
注意:Python 3.x では urlsafe_b64decode() はパディングあり・なし両方の入力を受け付けますが、文字が URL セーフ(-_)である場合に限ります。標準 Base64 文字列(+ または / を含む)を urlsafe_b64decode に渡してはいけません ——文字の不一致によりデータが黙って壊れるか、 binascii.Error が発生します。

Python でファイルと API レスポンスをエンコードする

本番コードでは、Base64 エンコードは送信されるファイルと、バイナリコンテンツを配信する外部 API からのレスポンスに最も頻繁に現れます。どちらのシナリオも、バイト境界の慎重な取り扱いが必要です。

ディスクからファイルを読み込んでエンコードする

Python 3.6+
import base64
import json
from pathlib import Path

def encode_file_to_base64(file_path: str) -> str:
    """バイナリファイルを読み込み、Base64 エンコードされた表現を返す。"""
    try:
        raw_bytes = Path(file_path).read_bytes()
        return base64.b64encode(raw_bytes).decode("ascii")
    except FileNotFoundError:
        raise FileNotFoundError(f"File not found: {file_path}")
    except PermissionError:
        raise PermissionError(f"Permission denied reading: {file_path}")

# TLS 証明書をデプロイメントマニフェストに添付
cert_b64 = encode_file_to_base64("./ssl/service-client.crt")

deployment_manifest = {
    "service":     "payment-processor",
    "environment": "production",
    "region":      "eu-west-1",
    "tls": {
        "client_cert":     cert_b64,
        "cert_format":     "base64-pem",
    },
}

# マニフェストを書き出す — 証明書が文字列として安全に埋め込まれる
with open("./dist/deployment-manifest.json", "w") as f:
    json.dump(deployment_manifest, f, indent=2)

print(f"Certificate encoded: {len(cert_b64)} characters")

デバッグ用に HTTP API レスポンスをエンコードする

Python 3.6+
import base64
import requests  # pip install requests

def fetch_and_encode_binary(url: str, headers: dict | None = None) -> str:
    """API からバイナリリソースを取得して Base64 として返す。"""
    response = requests.get(url, headers=headers or {}, timeout=10)
    response.raise_for_status()  # 4xx/5xx で HTTPError を発生させる

    content_type = response.headers.get("Content-Type", "unknown")
    encoded      = base64.b64encode(response.content).decode("ascii")

    print(f"Content-Type : {content_type}")
    print(f"生のサイズ   : {len(response.content):,} bytes")
    print(f"エンコード後 : {len(encoded):,} characters")
    return encoded

# 例:内部請求 API から署名済み PDF 請求書をダウンロード
invoice_b64 = fetch_and_encode_binary(
    "https://billing.internal/api/v2/invoices/INV-2026-0042/pdf",
    headers={"Authorization": "Bearer eyJhbGc..."},
)

# 通知ペイロードに添付
notification = {
    "recipient_id":  "team-finance",
    "invoice_id":    "INV-2026-0042",
    "attachment": {
        "filename":     "invoice-2026-0042.pdf",
        "content":      invoice_b64,
        "content_type": "application/pdf",
        "encoding":     "base64",
    },
}
print(f"Payload ready: {len(str(notification)):,} characters")

Python で画像ファイルを Base64 エンコードする方法

画像を Base64 にエンコードして data URI として埋め込む方法は、HTML メールテンプレート、PDF 生成、自己完結型 HTML スナップショットの標準的なアプローチです。ブラウザはエンコードされた文字列を直接解釈します——別途画像リクエストは不要です。同じパターンは PNG、JPEG、SVG、WebP、PDF などあらゆるバイナリファイル形式に使えます。

Python 3.6+
import base64
import mimetypes
from pathlib import Path

def image_to_data_uri(image_path: str) -> str:
    """画像ファイルを HTML インライン埋め込み用の Base64 data URI に変換する。"""
    path      = Path(image_path)
    mime_type = mimetypes.guess_type(image_path)[0] or "image/octet-stream"
    raw_bytes = path.read_bytes()
    encoded   = base64.b64encode(raw_bytes).decode("ascii")
    return f"data:{mime_type};base64,{encoded}"

# HTML メールテンプレートに製品画像をインライン埋め込み
hero_uri      = image_to_data_uri("./assets/product-hero-768px.png")
thumbnail_uri = image_to_data_uri("./assets/product-thumb-128px.webp")

html_fragment = f"""
<img src="{hero_uri}"
     alt="Product hero"
     width="768" height="432"
     style="display:block;max-width:100%" />
"""

print(f"PNG data URI starts with: {hero_uri[:60]}...")
# data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAwAAAAA...
注意:SVG ファイルの場合、URL エンコードの data URI(data:image/svg+xml,{encoded})は Base64 より小さくなることが多いです。SVG はテキストベースで、Base64 はサイズを約 33% 増加させるためです。ラスター形式(PNG、JPEG、WebP)には Base64 を使い、SVG には URL エンコードを使いましょう。

大きなファイルの処理 — チャンク Base64 エンコード

Path.read_bytes() でファイル全体をメモリに読み込む方法は、約 50 MB 以下のファイルなら問題ありません。それを超えると、ピーク時のメモリ使用量が大きくなります——200 MB のファイルは生バイト用に約 200 MB、Base64 出力用に約 267 MB が必要で、1 プロセスで合計約 467 MB になります。大きなファイルはチャンク単位で読み込んでエンコードしてください。

重要な制約:チャンクサイズは 3 バイトの倍数である必要があります。Base64 は入力 3 バイトをちょうど 4 つの出力文字にエンコードします。チャント境界が 3 の倍数でない位置にある場合、エンコーダはストリームの途中で = パディングを付加し、連結した出力が無効になります。

ファイルへのストリーミングエンコード(全ファイルのメモリロードなし)

Python 3.6+
import base64
from pathlib import Path

CHUNK_SIZE = 3 * 1024 * 256  # 786,432 バイト — 3 の倍数、約 768 KB/チャンク

def encode_large_file(input_path: str, output_path: str) -> int:
    """
    大きなバイナリファイルを全体をメモリに読み込まずに Base64 エンコードする。
    書き込まれた Base64 文字数を返す。
    """
    total_chars = 0
    with open(input_path, "rb") as src, open(output_path, "w") as dst:
        while True:
            chunk = src.read(CHUNK_SIZE)
            if not chunk:
                break
            encoded_chunk = base64.b64encode(chunk).decode("ascii")
            dst.write(encoded_chunk)
            total_chars += len(encoded_chunk)
    return total_chars

# アセット配信マニフェスト用に 300 MB の製品動画をエンコード
chars_written = encode_large_file(
    "./uploads/product-demo-4k.mp4",
    "./dist/product-demo-4k.b64",
)
print(f"Encoded: {chars_written:,} Base64 characters")
# Encoded: 407,374,184 Base64 characters

バイナリアセットディレクトリのエンコード(NDJSON 出力)

Python 3.6+
import base64
import json
from pathlib import Path

def encode_assets_to_ndjson(asset_dir: str, output_path: str) -> int:
    """
    ディレクトリ内のすべてのバイナリファイルを NDJSON マニフェストにエンコードする。
    各行は JSON オブジェクト: {"path": "...", "mime": "...", "data": "<base64>"}
    処理されたファイル数を返す。
    """
    import mimetypes

    asset_path = Path(asset_dir)
    count = 0

    with open(output_path, "w") as out:
        for file_path in sorted(asset_path.rglob("*")):
            if not file_path.is_file():
                continue
            mime = mimetypes.guess_type(str(file_path))[0] or "application/octet-stream"
            encoded = base64.b64encode(file_path.read_bytes()).decode("ascii")
            record  = {"path": str(file_path.relative_to(asset_path)), "mime": mime, "data": encoded}
            out.write(json.dumps(record) + "\n")
            count += 1

    return count

processed = encode_assets_to_ndjson("./dist/static/", "./dist/asset-bundle.ndjson")
print(f"Encoded {processed} files into NDJSON asset bundle")
注意:入力ファイルが約 50〜100 MB を超える場合、またはサービスが多くのファイルを並列処理しメモリ圧迫が懸念される場合は、read_bytes() からチャンク読み込みに切り替えてください。50 MB 未満のファイルには、よりシンプルな b64encode(path.read_bytes()).decode() の一行コードの方が高速で理解しやすいです。

Python でコマンドライン Base64 エンコードを行う

Python は base64 モジュールの CLI インターフェースを提供しています——追加ツールは不要です。クロスプラットフォームで動作するため、CI パイプラインや、システムの base64 コマンドが利用できない可能性がある Windows 環境で役立ちます。

bash
# ── python -m base64 ───────────────────────────────────────────────────
# 文字列をエンコード(パイプで stdin に渡す)
echo -n "deploy-svc:sk-prod-9f2a1c3e8b4d" | python3 -m base64
# ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==

# ファイルをエンコード
python3 -m base64 ./ssl/service-client.crt

# Base64 文字列をデコード
echo "ZGVwbG95LXN2Yzpzay1wcm9kLTlmMmExYzNlOGI0ZA==" | python3 -m base64 -d

# Base64 ファイルをバイナリに戻してデコード
python3 -m base64 -d ./dist/service-client.b64 > ./restored.crt

# ── Python ワンライナー — クロスプラットフォーム、Windows でも動作 ─────
# 文字列をエンコード
python3 -c "import base64,sys; print(base64.b64encode(sys.argv[1].encode()).decode())" "my-secret"
# bXktc2VjcmV0

# URL セーフエンコード(パディングなし)
python3 -c "import base64,sys; print(base64.urlsafe_b64encode(sys.argv[1].encode()).rstrip(b'=').decode())" "my-secret"
# bXktc2VjcmV0

# ファイルをインラインでエンコード(結果を stdout に出力)
python3 -c "import base64,sys; print(base64.b64encode(open(sys.argv[1],'rb').read()).decode())" ./config.json
注意:macOS のシステム base64 コマンドとは異なり、 python -m base64 はデフォルトで 76 文字での折り返しを行いません。出力は 1 行の連続した文字列になります。これは環境変数、JSON フィールド、HTTP ヘッダに必要な形式です。あらゆる OS でシステムの base64 の代替として使えます。

高性能な代替手段:pybase64

Python の stdlib の base64 モジュールは純粋な Python で実装されています(CPython には薄い C レイヤーがあります)。大きなペイロードを高スループットでエンコードするサービス——画像処理パイプライン、一括エクスポートジョブ、リアルタイムテレメトリ取り込み——には、 pybase64 が SIMD 加速 C ライブラリの libbase64 をバックエンドとするドロップイン代替品です。ペイロードサイズと CPU アーキテクチャに応じて 2〜10 倍のスループット向上がベンチマークで示されています。

bash
pip install pybase64
Python 3.6+
import pybase64
import time

# pybase64 はドロップイン代替品 — stdlib と同じ関数シグネチャ
sample_payload = b"x" * (1024 * 1024)  # 1 MB のバイナリデータ

# 標準エンコード — base64.b64encode() と同一の出力
encoded = pybase64.b64encode(sample_payload)
decoded = pybase64.b64decode(encoded)
assert decoded == sample_payload

# URL セーフエンコード — base64.urlsafe_b64encode() と同一の出力
url_safe = pybase64.urlsafe_b64encode(sample_payload)

# b64encode_as_string() は str を直接返す — .decode() 呼び出し不要
telemetry_event = b'{"event":"page_view","session_id":"sess_3a7f91c2","ts":1741824000}'
encoded_str: str = pybase64.b64encode_as_string(telemetry_event)

print(encoded_str[:48] + "...")
# eyJldmVudCI6InBhZ2VfdmlldyIsInNlc3Npb25faWQi...

# スループット比較(概算、ハードウェアにより異なる)
# stdlib  base64.b64encode(1 MB):   ~80 MB/s
# pybase64.b64encode(1 MB):         ~800 MB/s(AVX2 CPU の SIMD パス)

プロファイリングで Base64 エンコードがボトルネックと判明した場合、または約 100 KB 以上のペイロードを繰り返しエンコードする場合は pybase64 に切り替えてください。小さな文字列(認証情報、トークン)の一度きりのエンコードには、stdlib で十分高速でインストール依存もありません。

シンタックスハイライト付きターミナル出力

ターミナルで Base64 エンコードされたペイロード——特に JSON 設定や JWT の内容——をデバッグする際、rich ライブラリはシンタックスハイライト付きのインデントされた出力を提供し、生のダンプよりはるかに読みやすくなります。CLI ツール、デバッグスクリプト、REPL セッションで特に役立ちます。

bash
pip install rich
Python 3.6+
import base64
import json
from rich import print as rprint
from rich.syntax import Syntax
from rich.console import Console

console = Console()

def decode_and_pretty_print(encoded: str, label: str = "Decoded payload") -> None:
    """Base64 文字列をデコードし、JSON として解析してシンタックスハイライト付きで表示する。"""
    raw_bytes = base64.b64decode(encoded + "==")  # 寛容なパディング
    try:
        parsed  = json.loads(raw_bytes)
        pretty  = json.dumps(parsed, indent=2, ensure_ascii=False)
        syntax  = Syntax(pretty, "json", theme="monokai", line_numbers=False)
        console.rule(f"[bold blue]{label}")
        console.print(syntax)
    except json.JSONDecodeError:
        # JSON でない — 生テキストを表示
        console.rule(f"[bold yellow]{label} (raw text)")
        rprint(raw_bytes.decode("utf-8", errors="replace"))

# 認証失敗リクエストの JWT ペイロードセグメントを検査
jwt_payload_segment = "eyJzdWIiOiJ1c3JfN2MzYTlmMWIyZCIsInJvbGUiOiJkYXRhLWVuZ2luZWVyIiwiZXhwIjoxNzQxOTEwNDAwfQ"
decode_and_pretty_print(jwt_payload_segment, "JWT Payload")
注意:rich の出力はターミナル表示のみに使用してください——デバッグ、stdout へのログ記録、インタラクティブな CLI ツールに限ります。Base64 出力をファイルに書き込んだり、API エンドポイントから返したり、環境変数に保存したりするのには絶対に使わないでください。rich は ANSI エスケープコードを追加するため、データが壊れます。

よくあるミス

Base64 エンコードを含む多くの Python コードベースをレビューしてきましたが、以下の 4 つのミスが繰り返し見られます——非 ASCII 入力やバイナリファイルが本番環境のエンコードパスに入るまで、多くの場合気づかれません。

ミス 1 — b64encode() に bytes ではなく str を渡す

問題: b64encode() bytes オブジェクトを期待します。 str を渡すと直ちに TypeError: a bytes-like object is required が発生します。 修正: エンコード前に文字列に対して .encode("utf-8") を必ず呼び出す。

Before · Python
After · Python
import base64

# ❌ TypeError: a bytes-like object is required, not 'str'
webhook_secret = "wh-secret-a3f91c2b4d"
encoded = base64.b64encode(webhook_secret)  # crashes
import base64

# ✅ 先に str を bytes にエンコード
webhook_secret = "wh-secret-a3f91c2b4d"
encoded = base64.b64encode(webhook_secret.encode("utf-8"))
# b'd2gtc2VjcmV0LWEzZjkxYzJiNGQ='

ミス 2 — bytes の結果に .decode() を呼び忘れる

問題: b64encode() str ではなく bytes を返します。それを直接 f-string に埋め込むと出力に b'...' が含まれ、無効な HTTP ヘッダ値になり JSON シリアライズも壊れます。 修正: エンコード結果に常に .decode("ascii") を呼び出す。

Before · Python
After · Python
import base64

credential = base64.b64encode(b"svc-monitor:sk-7f3a1b")
# ❌ Authorization header contains "b'c3ZjLW1vbml0b3I6c2stN2YzYTFi'"
headers = {"Authorization": f"Basic {credential}"}
import base64

credential = base64.b64encode(b"svc-monitor:sk-7f3a1b").decode("ascii")
# ✅ Authorization: Basic c3ZjLW1vbml0b3I6c2stN2YzYTFi
headers = {"Authorization": f"Basic {credential}"}

ミス 3 — b64encode() が必要な場所で encodebytes() を使う

問題: encodebytes() は 76 文字ごとに \n を挿入し(MIME 折り返し)、末尾にも改行を追加します。これを JSON フィールド、環境変数、data URI に保存すると、リテラルの改行文字が埋め込まれ、下流でデータが壊れます。 修正: MIME メール作成以外のすべての場面では b64encode() を使う。

Before · Python
After · Python
import base64, json

cert_bytes = open("./ssl/root-ca.crt", "rb").read()
# ❌ encodebytes() は 76 文字ごとに \n を追加 — JSON と環境変数を壊す
cert_b64 = base64.encodebytes(cert_bytes).decode()
config   = json.dumps({"ca_cert": cert_b64})  # 文字列値の中に改行が含まれる
import base64, json
from pathlib import Path

cert_bytes = Path("./ssl/root-ca.crt").read_bytes()
# ✅ b64encode() は 1 行の連続した文字列を生成
cert_b64 = base64.b64encode(cert_bytes).decode("ascii")
config   = json.dumps({"ca_cert": cert_b64})  # クリーンな 1 行の値

ミス 4 — URL セーフ Base64 を標準デコーダでデコードする

問題: URL セーフ Base64 は + / の代わりに - _ を使います。URL セーフの文字列を b64decode() に渡すと、これらの文字が含まれるセグメントに対して誤ったバイトを黙って生成します——デフォルトでは例外が発生しません。 修正: URL セーフ入力には urlsafe_b64decode() を使うか、 validate=True を渡して早期に不一致を検出する。

Before · Python
After · Python
import base64

# ❌ JWT ペイロードセグメントは URL セーフ Base64 を使う(- と _)
# b64decode() はこれらの文字に対して誤ったバイトを黙って生成する
jwt_segment = "eyJzdWIiOiJ1c3JfN2MzYTlmMWIyZCIsInJvbGUiOiJhZG1pbiJ9"
wrong = base64.b64decode(jwt_segment)  # - や _ があれば黙って誤る
import base64

# ✅ JWT と URL セーフ入力には urlsafe_b64decode() を使う
jwt_segment = "eyJzdWIiOiJ1c3JfN2MzYTlmMWIyZCIsInJvbGUiOiJhZG1pbiJ9"
padding     = 4 - len(jwt_segment) % 4
raw         = base64.urlsafe_b64decode(jwt_segment + "=" * (padding % 4))
# b'{"sub":"usr_7c3a9f1b2d","role":"admin"}'

Python Base64 メソッド — クイック比較

メソッド入力型URL セーフ文字パディング改行戻り値インストール要否
b64encode()bytes, bytearray, memoryview❌ + と /✅ = padding❌ なしbytes不要
urlsafe_b64encode()bytes, bytearray, memoryview✅ - と _✅ = padding❌ なしbytes不要
b64encode(altchars=b"-_")bytes, bytearray, memoryview✅ カスタム 2 文字✅ = padding❌ なしbytes不要
encodebytes()bytes, bytearray, memoryview❌ + と /✅ = padding✅ \n 76文字ごとbytes不要
pybase64.b64encode()bytes, bytearray, memoryview❌ + と /✅ = padding❌ なしbytespip install
pybase64.b64encode_as_string()bytes, bytearray, memoryview❌ + と /✅ = padding❌ なしstrpip install

大多数のユースケースでは b64encode() を選んでください。HTTP ヘッダ、JSON フィールド、環境変数、data URI に適しています。出力が URL、ファイル名、クッキー、JWT セグメントに現れる場合は urlsafe_b64encode() に切り替えてください。 encodebytes() は MIME メール添付ファイルを作成する場合のみ使用してください——改行は MIME 仕様で必要ですが、他のすべてを黙って壊します。ホットパスで約 100 KB 以上のペイロードをエンコードする場合は pybase64 を活用してください。

よくある質問

なぜ base64.b64encode() は文字列ではなく bytes を返すのですか?
Python 3 はテキスト(str)とバイナリデータ(bytes)を厳格に分離しています。base64.b64encode() はバイナリデータを操作してバイナリデータを返します——出力文字がたまたま印刷可能な ASCII であっても。この設計は意図的なものです:エンコード境界を明示することを強制します。str を得るには、結果に対して .decode("ascii") または .decode("utf-8") を呼び出してください。有効な Base64 出力は ASCII 文字のみを含むため、どちらのエンコードも同一の結果を生成します。
Python の b64encode() と encodebytes() の違いは何ですか?
b64encode() は 1 行の連続した Base64 文字列を生成します——HTTP ヘッダ、JSON フィールド、data URI、環境変数、JWT セグメントに適した選択肢です。encodebytes()(Python 2 の encodestring())は 76 バイトごとに改行文字を挿入し、末尾にも改行を追加します。これは RFC 2045 で規定されたメール添付ファイルの MIME 折り返し形式です。メール作成以外で encodebytes() を使用すると、出力にリテラルの改行が埋め込まれ、ヘッダ、JSON 文字列、URL の値を壊します。
Python で非 ASCII 文字を含む文字列を Base64 エンコードするにはどうすればよいですか?
文字列に .encode("utf-8") を呼び出して bytes に変換し、その bytes を base64.b64encode() に渡してください。デコードする際は逆の手順を踏みます。base64.b64decode(encoded) の後、結果に .decode("utf-8") を呼び出します。UTF-8 はほぼすべてのテキストに適しています——キリル文字、CJK 表意文字、アラビア文字、絵文字を含むすべての Unicode コードポイントを処理できます。非 ASCII テキストに .encode("ascii") を使用すると UnicodeEncodeError が発生します。これは通常正しい動作で、エンコードの不一致を早期に表面化させます。
Python でファイルを Base64 エンコードするにはどうすればよいですか?
バイナリモードでファイルを読み込み、その bytes に base64.b64encode() を呼び出してください。最もシンプルなワンライナーは:encoded = base64.b64encode(Path("file.bin").read_bytes()).decode("ascii")。大きなファイル(約 50〜100 MB 以上)では、ファイル全体をメモリに読み込むのを避けてください。代わりに 3 バイトの倍数サイズのチャンクで読み込み(例:3 × 1024 × 256 = 786,432 バイト)、各チャンクを別々にエンコードします——3 の倍数サイズのチャンクを処理することで、出力の途中に余分な = パディング文字が現れるのを防げます。
Python の urlsafe_b64encode() がまだ = パディングを含むのはなぜですか?JWT はそれを使わないのに。
stdlib は RFC 4648 §5 仕様に従っており、= パディングを保持します。JWT(RFC 7519)はパディングを完全に除去する独自の Base64url エンコードを定義しています。この不一致は意図的な仕様の決定です:RFC 4648 のパディングは文字列を自己記述的にします(元のバイト長を常に決定できます)が、JWT はトークン長を短くするためにパディングを除去します。JWT 形式に合わせるには、エンコード後の出力に .rstrip(b"=") を呼び出してから .decode("ascii") を呼び出してください。デコードする際は正しいパディングを補完します:padding = 4 - len(segment) % 4; padded = segment + "=" * (padding % 4)。
デコード前に文字列が有効な Base64 かを検証する方法はありますか?
base64.b64decode() に validate=True を渡してください。このフラグを使用すると、標準 Base64 アルファベット(A–Z、a–z、0–9、+、/、=)以外の文字があると binascii.Error が発生します。validate=True がない場合、b64decode() は無効な文字を黙って無視するため、破損した入力を見逃す可能性があります。URL セーフ Base64 については urlsafe_b64decode() に validate パラメータがありません——正規表現で手動で検証できます:import re; bool(re.fullmatch(r"[A-Za-z0-9_-]+=*", segment))。信頼できない外部ソースからの入力は、デコードする前に常に検証してください。

関連ツール

Python コードを書かずにワンクリックでエンコードまたはデコードするには、文字列やファイルを Base64 Encoder に直接貼り付けてください——標準モードと URL セーフモードをブラウザ上で即座に処理します。セットアップは不要です。

他の言語でも利用可能:JavaScriptJava
MS
Maria SantosBackend Developer

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.

PS
Priya Sharma技術レビュアー

Priya is a data scientist and machine learning engineer who has worked across the full Python data stack — from raw data ingestion and cleaning to model deployment and monitoring. She is passionate about reproducible research, Jupyter-based workflows, and the practical engineering side of ML. She writes about NumPy, Pandas, data serialisation, and the Python patterns that make data pipelines reliable at scale.