この記事ではJavaScriptで『Base64エンコードとデコードする方法』について、
- btoa関数とatob関数を用いてBase64でエンコードとデコードする方法
- btoa関数で日本語をBase64エンコードする方法
- encodedURIComponent用いる方法
- encodedURIComponentとunescape用いる方法
- encodedメソッドでUint8Arrayに変換する方法
- Node.jsでBase64エンコードとデコードを行う方法
などをプログラム例を用いて分かりやすく説明するように心掛けています。ご参考になれば幸いです。
btoa関数とatob関数を用いてBase64でエンコードとデコードする方法
JavaScriptにはBase64でエンコードとデコードする関数(btoa
関数とatob
関数)が標準で用意されています。
btoa
関数- 文字列(string)をBase64形式のエンコード文字列(string)に変換する。
- 引数:文字列(string)
- 戻り値:エンコード文字列(string)
- 文字列(string)をBase64形式のエンコード文字列(string)に変換する。
atob
関数- Base64形式のエンコード文字列(string)を文字列(string)に変換する
- 引数:エンコード文字列(string)
- 戻り値:文字列(string)
- Base64形式のエンコード文字列(string)を文字列(string)に変換する
以下にbtoa
関数とatob
関数を用いたプログラム例を示しています。
// エンコードしたい文字列
const originalString = 'ABCD';
// btoaを使用してBase64エンコード
const base64EncodedString = btoa(originalString);
console.log(base64EncodedString); // QUJDRA==
// atobを使用してBase64デコード
const base64DecodedString = atob(base64EncodedString);
console.log(base64DecodedString); // ABCD
上記のプログラムでは「ABCD」をbtoa
関数を用いてBase64エンコードした後、atob
関数を用いてBase64デコードしています。
btoa関数で日本語をBase64エンコードする方法(encodedURIComponent用いる)
btoa
関数は日本語を直接エンコードすると、エラーが発生します(下記のエラーはGoogleのデベロッパーツールでのエラー結果です)。
btoa('テスト');
// エラーメッセージ
// Uncaught DOMException: Failed to execute 'btoa' on 'Window':
// The string to be encoded contains characters outside of the Latin1 range.
上記のエラーメッセージを見ると、「エンコードする文字列が Latin1 の範囲外の文字を含んでいます。」と記載されています。Base64エンコードするbtoa
関数は、Latin1の範囲内の文字しかエンコードすることができません。例えば、日本語などのマルチバイト文字はLatin1の範囲外の文字になるので、btoa
関数の引数に渡すとエラーになります。
Latin1で使える文字
Latin1で使える文字は以下のサイトで確認できます。
https://ja.wikipedia.org/wiki/ISO/IEC_8859-1
この場合、encodeURIComponent
関数でURIエンコードすることで、Latin1範囲外の文字(以下のプログラム例では日本語の「あ」)をLatin1で使える文字に変換することができます。なお、URIエンコードした文字をデコードする時には、decodeURIComponent
関数を用います。
// エンコードしたい文字列
const originalString = 'あ';
// encodeURIComponentを用いてURIエンコード
const uriEncodedString = encodeURIComponent(originalString);
console.log(uriEncodedString); // %E3%81%82
// btoaを使用してBase64エンコード
const base64EncodedString = btoa(uriEncodedString);
console.log(base64EncodedString); // JUUzJTgxJTgy
// atobを使用してBase64デコード
const base64DecodedString = atob(base64EncodedString);
console.log(base64DecodedString); // %E3%81%82
// decodeURIComponentを用いてデコード
const urlDecodedString = decodeURIComponent(base64DecodedString);
console.log(urlDecodedString); // あ
このプログラムでは、「あ」をencodeURIComponent
関数を用いてURIエンコードして「%E3%81%82」に変換した後、btoa
関数を用いてBase64エンコードしています。
encodeURIComponent
関数の返り値は%XX(XXは16進数)という形式の文字列になります。「16進数の数値」も「%(U+0025)」もLatin1で使える文字なので、encodeURIComponent関数の返り値は必ずLatin1範囲内の文字列になることが保証されます。
ただし、この方法だとBase64エンコードの結果が異なります。
本来、「あ」をBase64エンコードすると、「44GC」となるが、上記のプログラムでは「JUUzJTgxJTgy」になっています。これは、Base64エンコードをするbtoa
関数は引数として渡した文字列の文字1つ1つを1バイトのデータとみなすからです。「あ」をURIエンコードした結果の文字列「%E3%81%82」をbtoa
関数の引数に渡しているので、Base64エンコードした結果が「JUUzJTgxJTgy」になっています。
次に、「あ」をBase64エンコードした結果が正しく「44GC」になる方法を説明します。
btoa関数で日本語をBase64エンコードする方法(encodedURIComponentとunescape用いる)
encodeURIComponent
関数とdecodeURIComponent
関数に加えて、unescape
関数とescape
関数を用いると、「あ」をBase64エンコードした結果が正しく「44GC」になります。encodeURIComponent
関数でURIエンコードした後に、unescape
関数を用いることで、正しく btoa
関数で処理できる形式に変換することができるのです。
では実際のプログラム例を見てみましょう。
// エンコードしたい文字列
const originalString = 'あ';
// encodeURIComponentを用いてURIエンコード
const uriEncodedString = encodeURIComponent(originalString);
console.log(uriEncodedString); // %E3%81%82
// unescapeを用いてアンエスケープ(実際にはUTF-8のバイト列をLatin1文字列として取得)
const utf8ToLatin1String = unescape(uriEncodedString);
console.log(utf8ToLatin1String); // ã
// btoaを使用してBase64エンコード
const base64EncodedString = btoa(utf8ToLatin1String);
console.log(base64EncodedString); // 44GC
// atobを使用してBase64デコード
const base64DecodedString = atob(base64EncodedString);
console.log(base64DecodedString); // ã
// escapeを用いて再エスケープ(Latin1文字列をUTF-8のパーセントエンコードに変換)
const latin1StringToUtf8 = escape(base64DecodedString);
console.log(latin1StringToUtf8); // %E3%81%82
// decodeURIComponentを用いてデコード
const urlDecodedString = decodeURIComponent(latin1StringToUtf8);
console.log(urlDecodedString); // あ
unescape('%E3%81%82')
をコンソール出力すると「ã」だけが表示されています。これは、E3が「ã」にデコードされ、「ã」に続く2バイトがLatin-1の非表示文字として解釈されるからです。
btoa関数で日本語をBase64エンコードする方法(encodedメソッドでUint8Arrayに変換する)
unescape
関数とescape
関数を使うと簡単にBase64エンコードとデコードすることができますが、これらの関数は現在、非推奨の関数になっています。
unescape
関数とescape
関数を用いずに、btoa
関数で日本語をBase64エンコードするためには、以下の方法を用います。
- 文字列をUint8Arrayに変換後、Latin1文字列にして、Base64エンコードする。
- 文字列をUint8Arrayに変換するためには、TextEncoder.prototype.encodeを用いる。
- Base64エンコードした結果を、Latin1文字列変換後、Uint8Arrayにして、文字列に変換する
- Uint8Arrayを文字列に変換するためには、TextDecoder.prototype.decodeを用いる。
では実際のプログラム例を見てみましょう。
// エンコードしたい文字列
const originalString = 'あ';
// 文字列をTextEncoderを使用してUint8Arrayに変換
const encoder = new TextEncoder();
const uint8Arr = encoder.encode(originalString);
console.log(uint8Arr); // [ 227, 129, 130 ]
// Uint8ArrayをLatin1文字列に変換
const uint8ArrToLatin1String = Array.from(uint8Arr)
.map((byte) => String.fromCharCode(byte))
.join('');
console.log(uint8ArrToLatin1String); // ã
// btoaを使用してBase64エンコード
const base64EncodedString = btoa(uint8ArrToLatin1String);
console.log(base64EncodedString); // 44GC
// atobを使用してBase64デコード
const base64DecodedString = atob(base64EncodedString);
console.log(base64DecodedString); // ã
// Latin1文字列をUint8Arrayに変換
const latin1StringToUint8Arr = new Uint8Array(
base64DecodedString.split('').map((char) => char.charCodeAt(0))
);
console.log(latin1StringToUint8Arr); // [ 227, 129, 130 ]
// Uint8Arrayを文字列にデコード
const decoder = new TextDecoder();
const decodedString = decoder.decode(latin1StringToUint8Arr);
console.log(decodedString); // あ
Node.jsでBase64エンコードとデコードを行う方法
Node.jsでBase64エンコードとデコードを行う場合、組み込みのBuffer
クラスを使用するのが一般的です。以下は、Node.jsを使用して日本語をBase64エンコードおよびデコードする方法を示すプログラム例です。
// エンコードしたい文字列
const originalString = 'あ';
// 文字列をBufferに変換
const buffer = Buffer.from(originalString);
console.log(buffer); // <Buffer e3 81 82>
// BufferからBase64エンコードされた文字列を取得
const base64EncodedString = buffer.toString('base64');
console.log(base64EncodedString); // 44GC
// Base64エンコードされた文字列をBufferに変換
const bufferFromBase64 = Buffer.from(base64EncodedString, 'base64');
console.log(bufferFromBase64); // <Buffer e3 81 82>
// Bufferからデコードされた文字列を取得
const decodedString = bufferFromBase64.toString();
console.log(decodedString); // あ
Buffer
クラスは、多くの機能を持っています。
例えば、文字列やバイナリデータをBase64形式にエンコードしたり、Base64形式からデコードしたりする機能があります。これらの機能は、toString('base64')
やBuffer.from(string, 'base64')
のようなメソッドを用います。
toString('base64')
- バイナリデータ(Buffer)をBase64エンコードされた文字列に変換する。
Buffer.from(string, 'base64')
- Base64エンコードされた文字列をバイナリデータ(バッファ)に変換(デコード)する。
本記事のまとめ
この記事ではJavaScriptで『Base64エンコードとデコードする方法』について、以下の内容を説明しました。
- btoa関数とatob関数を用いてBase64でエンコードとデコードする方法
- btoa関数で日本語をBase64エンコードする方法
- encodedURIComponent用いる方法
- encodedURIComponentとunescape用いる方法
- encodedメソッドでUint8Arrayに変換する方法
- Node.jsでBase64エンコードとデコードを行う方法
お読み頂きありがとうございました。