バイナリデータのBase64エンコード
画像、PDF、実行ファイルなどのバイナリデータをBase64でエンコードする方法を解説。バイトレベルの処理、型付き配列、ストリーミングアプローチを紹介します。
詳細な説明
Base64はバイナリデータをテキストとしてエンコードするために設計されました。文字列入力でのデモが一般的ですが、その本来の目的はJSON、XML、メールなどのテキストベース形式で直接表現できない生のバイトを扱うことです。
バイナリデータとは?
プレーンテキスト以外のすべてのデータ:画像(PNG、JPEG、WebP)、ドキュメント(PDF、DOCX)、アーカイブ(ZIP、TAR)、オーディオ(MP3、WAV)、ビデオ(MP4)、実行ファイル、シリアライズされたオブジェクト、暗号鍵、0-255の全範囲のバイト値を含むあらゆるファイルです。
JavaScriptでのバイナリデータの操作:
ブラウザはバイナリ操作のための型付き配列を提供します:
// Create binary data
const bytes = new Uint8Array([0x89, 0x50, 0x4E, 0x47]); // PNG magic bytes
// Encode to Base64
const binaryString = Array.from(bytes, b => String.fromCharCode(b)).join("");
const base64 = btoa(binaryString);
// Decode from Base64
const decoded = atob(base64);
const decodedBytes = Uint8Array.from(decoded, c => c.charCodeAt(0));
ブラウザでファイルをバイナリとして読み取る:
const input = document.querySelector('input[type="file"]');
input.addEventListener("change", async () => {
const file = input.files[0];
const arrayBuffer = await file.arrayBuffer();
const bytes = new Uint8Array(arrayBuffer);
// Convert to Base64
let binary = "";
for (let i = 0; i < bytes.length; i++) {
binary += String.fromCharCode(bytes[i]);
}
const base64 = btoa(binary);
});
大きなファイルのチャンクエンコード:
数メガバイトを超えるファイルでは、一括エンコードするとブラウザがフリーズしたりメモリ不足エラーが発生する可能性があります。チャンク方式ではデータを分割して処理します:
async function encodeFileChunked(file, chunkSize = 1024 * 1024) {
const reader = file.stream().getReader();
const chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
}
// Combine and encode (simplified)
const combined = new Uint8Array(chunks.reduce((a, c) => a + c.length, 0));
let offset = 0;
for (const chunk of chunks) {
combined.set(chunk, offset);
offset += chunk.length;
}
return btoa(String.fromCharCode(...combined));
}
Node.jsではBufferがすべてを処理:
const fs = require("fs");
const fileBuffer = fs.readFileSync("data.bin");
const base64 = fileBuffer.toString("base64");
const restored = Buffer.from(base64, "base64");
重要なポイント: 文字セットやエンコーディング(UTF-8、Latin-1)を気にするテキストエンコードとは異なり、バイナリからBase64への変換は単純明快です。バイトを直接Base64アルゴリズムに入力するため、文字エンコーディングのステップがありません。
ユースケース
テキストフレームのみをサポートするWebSocket接続を介して、クライアント側で生成した暗号鍵ペアを送信する際に、Base64で生のキーバイトをシリアライズする場合に使用します。