Base64エンコード&デコード:いつ、どのように使用するか

· 12分で読む

目次

Base64エンコードとは?

Base64は、バイナリデータをASCII文字列に変換するバイナリからテキストへのエンコード方式です。64個の印刷可能な文字(A-Z、a-z、0-9、+、/)とパディング用の等号(=)を使用します。「Base64」という名前は、バイナリデータを表現するために64個の異なる文字のベースを使用することに由来しています。

Base64が不可欠な理由は次のとおりです:テキスト専用に設計されたシステムを通じて、バイナリデータを安全に転送できるようにします。Base64以前は、電子メールで画像を送信したり、JSONにバイナリデータを埋め込んだりすると、データが破損したり、システムが完全に壊れたりしていました。

Base64は暗号化ではありません — これは重要な区別です。セキュリティや難読化は一切提供しません。誰でもキーやパスワードなしで即座にBase64をデコードできます。これは純粋に互換性のために設計されたエンコード方式であり、機密性のためではありません。

Base64には毎日遭遇していますが、多くの場合気づいていません:

🛠️ 試してみてください: 当社のBase64エンコーダー/デコーダーを使用して、ブラウザでデータを即座にエンコードおよびデコードできます。

Base64の内部動作

Base64は、入力データの3バイト(24ビット)ごとに4文字(各6ビット)に変換します。この数学的関係が、Base64がテキストに変換しながらデータの整合性を維持する方法の基礎となっています。

テキスト「Hi」をエンコードする完全な例を見てみましょう:

  1. ASCIIバイトに変換: 「Hi」は72、105になります
  2. バイナリに変換: 01001000 01101001(合計16ビット)
  3. 6ビットのチャンクにグループ化: 010010 | 000110 | 1001xx
  4. 不完全なグループをパディング: 010010 | 000110 | 100100
  5. Base64アルファベットにマッピング: S(18)、G(6)、k(36)
  6. パディング文字を追加: SGk=

パディング文字(=)は、最終グループから何バイト欠けていたかを示します。=が1つの場合は1バイトが欠けており、=が2つの場合は2バイトが欠けていたことを意味します。

Base64文字セット

標準のBase64エンコーディングで使用される64文字は、異なるシステム間で普遍的に安全であるように慎重に選択されています:

範囲 文字
大文字 A-Z 0-25
小文字 a-z 26-51
数字 0-9 52-61
特殊文字 +/ 62-63
パディング = 該当なし

サイズのトレードオフ

入力の3バイトごとに出力の4文字になるため、Base64はデータサイズを約33%増加させます。これは、テキストセーフな転送を実現するための基本的なトレードオフです。

例えば:

このサイズの増加は、Base64がユースケースに適しているかどうかを決定する際に考慮すべき重要な点です。

Base64を使用するタイミング

Base64は、バイナリデータがテキスト専用システムを通過する必要がある特定のシナリオで威力を発揮します。これらのユースケースを理解することで、エンコーディングが適切な場合について情報に基づいた決定を下すことができます。

電子メールの添付ファイルとMIME

SMTP(Simple Mail Transfer Protocol)は、1982年に7ビットASCIIテキスト専用に設計されました。PDF、画像、またはバイナリファイルを電子メールに添付すると、電子メールクライアントによって自動的にBase64エンコードされます。

MIME(Multipurpose Internet Mail Extensions)標準は、バイナリ添付ファイルの主要なエンコード方法としてBase64を使用します。これにより、通過する電子メールサーバーに関係なく、ファイルが無傷で到着することが保証されます。

Web開発におけるデータURL

データURLを使用すると、別のHTTPリクエストを行う代わりに、小さなファイルをHTML、CSS、またはJavaScriptに直接埋め込むことができます。これは特に次の場合に便利です:

データURLの構造例:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...

API認証

HTTP Basic認証は、資格情報をBase64形式でエンコードします。ユーザー名とパスワードを送信すると、コロンで結合され、Base64エンコードされます:

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

このエンコーディングにより、ヘッダーがHTTP送信に対して安全になりますが、資格情報は簡単にデコードされます(そのためHTTPSが不可欠です)。

JSONとXMLデータ転送

JSONとXMLは、バイナリデータを直接含むことができないテキストベースの形式です。これらの形式にバイナリコンテンツを含める必要がある場合、Base64エンコーディングが標準的なソリューションです:

JWTトークン

JSON Web Tokenは、ヘッダー、ペイロード、署名の3つのコンポーネントにBase64URLエンコーディング(URLセーフバリアント)を使用します。これにより、JWTをURL、HTTPヘッダー、Cookieで安全に送信できます。

プロのヒント: 当社のJWTデコーダーを使用して、JWTトークンを検査および検証してください。Base64エンコードされたコンポーネントがリアルタイムでデコードされるのを確認できます。

JavaScriptでのBase64

JavaScriptは、Base64エンコードとデコードのための組み込み関数を提供していますが、ブラウザ環境とNode.js環境では動作が異なります。

ブラウザ環境

最新のブラウザには、btoa()(バイナリからASCII)とatob()(ASCIIからバイナリ)関数が含まれています:

// エンコード
const encoded = btoa('Hello, World!');
console.log(encoded); // SGVsbG8sIFdvcmxkIQ==

// デコード
const decoded = atob('SGVsbG8sIFdvcmxkIQ==');
console.log(decoded); // Hello, World!

重要な制限: btoa()は、Latin1範囲(0-255)の文字を含む文字列でのみ機能します。Unicode文字列の場合は、追加のステップが必要です:

// Unicode文字列のエンコード
function encodeUnicode(str) {
  return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
    (match, p1) => String.fromCharCode('0x' + p1)
  ));
}

// Unicode文字列のデコード
function decodeUnicode(str) {
  return decodeURIComponent(atob(str).split('').map(c =>
    '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
  ).join(''));
}

const encoded = encodeUnicode('Hello 世界');
console.log(encoded); // SGVsbG8g5LiW55WM

Node.js環境

Node.jsは、Base64操作にBuffer APIを使用し、バイナリデータとUnicodeを正しく処理します:

// エンコード
const encoded = Buffer.from('Hello, World!').toString('base64');
console.log(encoded); // SGVsbG8sIFdvcmxkIQ==

// デコード
const decoded = Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64').toString('utf8');
console.log(decoded); // Hello, World!

// Unicodeで完璧に動作
const unicodeEncoded = Buffer.from('Hello 世界').toString('base64');
console.log(unicodeEncoded); // SGVsbG8g5LiW55WM

Node.jsでのファイルのエンコード

Node.jsでファイルを読み取ってエンコードするのは簡単です:

const fs = require('fs');

// ファイルを読み取ってエンコード
const fileBuffer = fs.readFileSync('image.png');
const base64Image = fileBuffer.toString('base64');

// エンコードされたデータを保存
fs.writeFileSync('image.txt', base64Image);

// デコードして保存
const decodedBuffer = Buffer.from(base64Image, 'base64');
fs.writeFileSync('image-copy.png', decodedBuffer);

クイックヒント: 大きなファイルの場合は、ファイル全体をメモリに読み込む代わりにストリームを使用してください。これにより、数メガバイトのファイルでのメモリの問題を防ぐことができます。

PythonでのBase64

Pythonのbase64モジュールは、優れたUnicodeサポートを備えた包括的なエンコードおよびデコード機能を提供します。

基本的なエンコードとデコード

import base64

# 文字列のエンコード
text = "Hello, World!"
encoded = base64.b64encode(text.encode('utf-8'))
print(encoded)  # b'SGVsbG8sIFdvcmxkIQ=='

# デコード
decoded = base64.b64decode(encoded).decode('utf-8')
print(decoded)  # Hello, World!

# Unicodeはシームレスに動作
unicode_text = "Hello 世界"
encoded_unicode = base64.b64encode(unicode_text.encode('utf-8'))
print(encoded_unicode)  # b'SGVsbG8g5LiW55WM'

ファイルの操作

Pythonはファイルのエンコードとデコードを簡単にします:

import base64

# ファイルをエンコード
with open('image.png', 'rb') as file:
    encoded = base64.b64encode(file.read())
    
with open('image.txt', 'wb') as file:
    file.write(encoded)

# ファイルをデコード
with open('image.txt', 'rb') as file:
    decoded = base64.b64decode(file.read())
    
with open('image-copy.png', 'wb') as file:
    file.write(decoded)

URLセーフエンコーディング

Pythonには、問題のある文字を置き換えるURLセーフなBase64バリアントが含まれています:

import base64

text = "Hello, World!"
encoded_bytes = text.encode('utf-8')

# 標準のBase64
standard = base64.b64encode(encoded_bytes)
print(standard)  # b'SGVsbG8sIFdvcmxkIQ=='

# URLセーフなBase64(+を-に、/を_に置き換え)
urlsafe = base64.urlsafe_b64encode(encoded_bytes)
print(urlsafe)  # b'SGVsbG8sIFdvcmxkIQ=='

# URLセーフのデコード
decoded = base64.urlsafe_b64decode(urlsafe).decode('utf-8')
print(decoded)  # Hello, World!

データURLのエンコード

Web使用のためにPythonでデータURLを作成:

import base64
import mimetypes

def create_data_url(filepath):
    mime_type, _ = mimetypes.guess_type(filepath)
    with open(filepath, 'rb') as file:
        encoded = base64.b64encode(file.read()).decode('utf-8')
    return f"data:{mime_type};base64,{encoded}"

# 使用法
data_url = create_data_url('logo.png')
print(data_url[:50])  # data:image/png;base64,iVBORw0KGgoAAAANSUhEU...

コマンドラインでのBase64

Unix系システムには、ターミナルで直接エンコードおよびデコード操作を迅速に行うためのbase64コマンドが含まれています。

基本的な使用法

# 文字列をエンコード
echo "Hello, World!" | base64
# 出力: SGVsbG8sIFdvcmxkIQo=

# 文字列をデコード
echo "SGVsbG8sIFdvcmxkIQo=" | base64 -d
# 出力: Hello, World!

# ファイルをエンコード
base64 image.png > image.txt

# ファイルをデコード
base64 -d image.txt > image-copy.png

# 改行なしでエンコード(データURLに便利)
base64 -w 0 image.png > image-oneline.txt

macOSの違い

macOSでは、base64コマンドのオプションが若干異なります:

# macOSでデコード
base64 -D image.txt > image-copy.png

# macOSで改行なしでエンコード
base64 -b 0 image.png > image-oneline.txt

実用的なコマンドラインの例

# 画像からデータURLを作成
echo "data:image/png;base64,$(base64 -w 0 logo.png)"

# クリップボードの内容をエンコード(xclipを使用したLinux)
xclip -o | base64

# クイックAPI認証ヘッダー
echo -n "username:password" | base64
# 出力: dXNlcm5hbWU6cGFzc3dvcmQ=

# エンコード/デコード後のファイル整合性を検証
md5sum original.pdf
base64 original.pdf | base64 -d | md5sum
# 両方のチェックサムが一致する必要があります

プロのヒント: データURLを作成する際は、base64 -w 0(Linux)またはbase64 -b 0(macOS)を使用して、URL形式を壊す改行を避けてください。

データURLとインライン画像

データURLは、Base64エンコーディングを使用して、ファイルコンテンツをHTML、CSS、またはJavaScriptに直接埋め込みます。これにより