AYAME

Base64の仕組み(3バイト→4文字、パディング)

公開日:

Base64は、バイナリデータを英数字と一部の記号だけで表すための符号化方式です。メールやJSON、URLなど、バイナリをそのまま扱えない場所にデータを埋め込むときに使われます。暗号化ではなく、誰でも元に戻せる変換です。たとえばHTMLやCSSの中に小さな画像データを直接埋め込む「データURI」(data:image/png;base64,...)でも、画像のバイナリをBase64にした文字列が使われています。

3バイトを4文字に変換する仕組み

Base64は、入力を24ビット(3バイト)ごとのまとまりに分け、それぞれを6ビットずつの4つの値に分割し、64種類の文字(A〜Z、a〜z、0〜9、+、/)に対応させて4文字で表します。たとえば文字列「AYA」(UTF-8で3バイト、65,89,65)をBase64にすると「QVlB」という4文字になります。3バイトという単位は、24が6の倍数であり、8(1バイト)の倍数でもあるために選ばれています。

サイズが約4/3倍になる理由とパディング

3バイトの入力が4文字の出力になるため、全体のサイズは元のデータの4/3倍、つまり約1.33倍になります。入力のバイト数が3の倍数でない場合は、足りない分を0で埋めて計算し、出力の末尾に「=」を付けて長さを調整します。たとえば1バイトの「A」をBase64にすると「QQ==」(4文字中2つがパディング)、5バイトの「AYAME」は「QVlBTUU=」(8文字中1つがパディング)になります。

日本語などの扱い

日本語の文字列をBase64にするときは、先にUTF-8のバイト列に変換してから符号化します。たとえば「こんにちは」はUTF-8で15バイトになり、Base64では「44GT44KT44Gr44Gh44Gv」という20文字になります。15バイトは3の倍数なのでパディングは付きません。UTF-8以外の文字コードのまま符号化すると、デコードした側で文字化けの原因になるため、エンコードとデコードで同じ文字コードを使うことが重要です。

URLセーフな形式

標準のBase64は64種類の文字に+(プラス)と/(スラッシュ)を含みますが、この2文字はURLやファイル名ではそのまま使えないことがあります。RFC 4648はこの問題に対応するため、+を-(ハイフン)に、/を_(アンダースコア)に置き換えた「URLセーフ」の変形を定めています。パディングの=も、URLの区切り文字と混同しやすいため、省略して使われることがあります。デコードする側は、どちらの形式で符号化されたかを確認する必要があります。

参考資料

この記事の変換はBase64変換ツールでも確認できます。

関連記事