コンテンツにスキップ

Base64エンコードでファイルサイズが33%増える理由

カテゴリ:エンコード

「Base64でエンコードするとファイルサイズが約33%増える」と聞いたことはありませんか? これはなぜなのでしょうか。この記事では、Base64エンコードの仕組みと、ファイルサイズが増加する数学的な理由、そして開発現場での影響を解説します。

Base64とは何か

Base64は、バイナリデータをASCII文字のみで表現するエンコード方式です。メールの添付ファイル(MIME)、データURIスキーム、JWTトークン、Basic認証ヘッダーなど、テキストしか扱えないプロトコルでバイナリデータを送受信するために使われます。

使用する文字は A–Z(26文字)、a–z(26文字)、0–9(10文字)、+/ の合計64文字(=Base64)と、パディング用の = です。

なぜ33%増えるのか

Base64は 3バイトのバイナリを4文字のASCIIに変換 します。

  • 3バイト = 24ビット
  • 24ビット ÷ 6ビット = 4つのBase64文字(各文字は6ビットを表す)

つまり、元データの 3バイト → 4文字 になります。サイズ比は 4 ÷ 3 ≈ 1.333... なので、約33.3%増加 します。

元バイナリ:   | 0x4D | 0x61 | 0x6E |  ← 3バイト
              01001101 01100001 01101110
              ↓ 6ビットずつに分割
              010011 010110 000101 101110
              ↓ Base64文字に変換
                 T       W       F       u   ← 4文字(= 4バイト)

具体的なサイズ増加の計算

元のファイルサイズBase64後のサイズ増加量
1 MB(1,000,000 B)約 1.333 MB+333 KB
10 MB約 13.33 MB+3.33 MB
25 MB(Gmail上限)約 33.3 MB+8.33 MB
100 MB約 133.3 MB+33.3 MB

正確な計算式は以下の通りです。

import math

def base64_size(original_bytes: int) -> int:
    """Base64エンコード後のバイト数を計算"""
    # 3バイトを4文字に変換、4の倍数にパディング
    return math.ceil(original_bytes / 3) * 4

original = 10_000_000  # 10 MB
encoded  = base64_size(original)
print(f"元: {original:,} B")
print(f"後: {encoded:,} B")
print(f"増加率: {encoded/original*100:.1f}%")
# → 元: 10,000,000 B
# → 後: 13,333,336 B
# → 増加率: 133.3%

改行文字によるさらなる増加

MIME規格(メール)では、Base64のデータを76文字ごとに \r\n(CRLF)で改行することが求められます。この改行も追加のバイトとなるため、サイズが若干さらに増加します。

def base64_mime_size(original_bytes: int, line_length: int = 76) -> int:
    """MIME形式(76文字改行)のBase64サイズを計算"""
    b64_chars = math.ceil(original_bytes / 3) * 4
    line_count = math.ceil(b64_chars / line_length)
    return b64_chars + line_count * 2  # CRLF = 2バイト/行

開発への影響

APIでのファイル送信

REST APIでファイルをJSONボディに含めて送る場合、Base64エンコードが必要になります。

// ファイルをBase64に変換してJSONで送る
const file = document.getElementById('file').files[0];
const reader = new FileReader();
reader.onload = (e) => {
    const base64 = e.target.result; // "data:image/png;base64,iVBORw0KGgo..."
    fetch('/api/upload', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ file: base64, name: file.name })
    });
};

このとき、APIのリクエストサイズ上限はBase64後のサイズで判断されます。10MBのファイルを送る場合、JSONボディは約13.3MB以上になることに注意してください。

メール添付(SMTP)

SMTPプロトコルはASCIIテキストベースのため、添付ファイルはBase64でエンコードされます。Gmailの添付上限は25MBですが、これはエンコード前のファイルサイズが対象です(内部でのエンコードはGmailが処理)。ただし、SMTP経由で直接送信する場合はエンコード後のサイズが制限の対象となるため注意が必要です。

img タグのdata URI

<!-- Base64埋め込み画像 -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." />

HTMLに画像をインライン埋め込みする場合も、画像のBase64サイズ分だけHTMLファイルが大きくなります。大きな画像のインライン埋め込みはページ読み込み速度に影響するため避けるのが一般的です。

Base64をデコードして元のサイズに戻す

まとめ

  • Base64は 3バイト → 4文字 に変換するため、サイズが 約33.3%増加 する
  • MIME改行(76文字ごと)があるとさらにわずかに増加する
  • JSONボディでファイルを送るAPIでは、Base64後のサイズでリクエスト上限が決まる
  • HTMLフォームの multipart/form-data ではBase64エンコードは不要(バイナリのまま送信)

この記事で使えるテストファイル

📚 関連記事

PNG vs WebP vs AVIF|画像フォーマットの選び方と変換方法

PNG / JPEG / WebP / AVIF の特徴・用途・ブラウザ対応状況を比較。picture 要素での出し分け、DevLab の画像フォーマット変換ツールの使い方も解説。

2026-04-18

Whois でドメイン情報を調べる方法|有効期限・ネームサーバー・登録者

Whois でわかること (登録者・有効期限・レジストラ・NS)、GDPR によるプライバシー保護の影響、ドメイン管理の実務的な使い方を解説。

2026-04-18

HTTP ステータスコード完全ガイド|よくあるエラーの原因と対処法

開発者が頻出する HTTP ステータスコード (200/301/302/400/401/403/404/413/422/429/500/502/503/504) の意味・原因・対処法を解説。301 vs 302 の SEO 影響、400 vs 422 の使い分けも。

2026-04-18

cURL コマンドを JavaScript fetch・Python requests に変換する方法|DevTools 連携

Chrome DevTools の Copy as cURL を fetch / axios / Python requests / PHP cURL / Go net/http に変換する手順を解説。主要 cURL オプション (-X / -H / -d / -F / -u / -b / -L) の変換パターン、認証トークンの扱い、注意点まで。

2026-04-16

Cookie のセキュリティフラグ完全ガイド|Secure / HttpOnly / SameSite / __Host-

Cookie のセキュリティ属性 Secure / HttpOnly / SameSite (Strict/Lax/None) / __Host- __Secure- プレフィックス / 4096 バイト制限を解説。CSRF / XSS / セッションハイジャック対策と、Laravel / Express の実装例。

2026-04-16

JWT のセキュリティベストプラクティス|alg none 攻撃 / 有効期限 / 署名検証

JWT (JSON Web Token) の代表的な脆弱性 6 種類 (alg none 攻撃 / 鍵混同 / 無期限トークン / payload への機密情報 / 失効不可 / 弱いシークレット) と対策。リフレッシュトークンパターン、失効リスト、HttpOnly Cookie 格納まで。

2026-04-16