任意のデータとBase64の相互変換.js
window.btoa()は1バイト文字しか変換できませんが、他バイト文字を含むテキストやテキスト以外のデータもBase64と相互変換できてほしいですよね? しょうがないのでラッパーを書きましょう
ポイントは「Uint8Arrayを経由することで8bit(1byte)ごとにわけてbtoaセーフな文字列を作ること」「TextEncoder・TextDecoderを使うとStringとUint8Arrayの相互変換ができること」
code:script.js
const Base64 = class Base64 {
/**
* @param {Uint8Array} data - Base64エンコードしたいデータ
* @return {string} - Base64文字列
*/
static encode(data) {
/** @type {string} Unit8Arrayを要素ごとに対応する文字に置き換えた配列をjoinした文字列 */
const bin = Array.from(data, el => String.fromCodePoint(el)).join("");
/** @type {string} binをBase64変換した文字列 */
const encoded = window.btoa(bin);
return encoded;
}
/**
* @param {string} str - デコードしたいBase64文字列
* @return {Uint8Array} - デコードされたデータ
*/
static decode(str) {
/** @type {string} strをデコードした文字列 */
/** @type {string} strをデコードした文字列 */
const decoded = window.atob(str);
/** @type {Uint8Array} デコードした文字列を1文字ずつコードポイントに変換したUint8Array */
const arr = Uint8Array.from(decoded, l => l.codePointAt(0));
return arr;
}
/**
* @param {string} text - Base64エンコードしたい文字列
* @return {string} - Base64文字列
*/
static encodeText(text) {
return this.encode(new TextEncoder().encode(text));
}
/**
* @param {string} str - デコードしたいBase64文字列
* @return {string} - デコードされた文字列
*/
static decodeToText(str) {
return new TextDecoder().decode(this.decode(str));
}
/**
* @param {Blob} blob - Base64エンコードしたいBlob
* @return {string} - Base64文字列
*/
static encodeBlob(blob) {
return this.encode(Uint8Array.from(blob.arrayBuffer()));
}
/**
* @param {string} str - デコードしたいBase64文字列
* @return {Blob} - デコードされたBlob
*/
static decodeToBlob(text) {
return new Blob(this.decode(text));
}
};