====== Base64 エンコード/デコード ====== ===== 文字列の Base64 エンコード/デコード ===== **[[https://developer.mozilla.org/ja/docs/Web/API/WindowBase64/btoa|encodedData = window.btoa(stringToEncode)]]** - Web API | MDN\\ **[[https://developer.mozilla.org/ja/docs/Web/API/WindowBase64/atob|decodedData = window.atob(encodedData)]]** - Web API | MDN\\ を利用した例は以下のようになる。\\ js > btoa('Hello World!') SGVsbG8gV29ybGQh js > atob('SGVsbG8gV29ybGQh') Hello World! js > btoa('🐍') InvalidCharacterError: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range. js > btoa(unescape(encodeURIComponent('🐍'))) 8J+QjQ== js > decodeURIComponent(escape(atob('8J+QjQ=='))) 🐍 ===== byteArray を自前でエンコード/デコードするコード ===== class Base64 { static base64Encode(byteArray) { let base64 = ''; const encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; const bytes = new Uint8Array(byteArray); const byteLength = bytes.byteLength; const byteRemainder = byteLength % 3; const mainLength = byteLength - byteRemainder; let a, b, c, d; let chunk; // Main loop deals with bytes in chunks of 3 for (var i = 0; i < mainLength; i = i + 3) { // Combine the three bytes into a single integer chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; // Use bitmasks to extract 6-bit segments from the triplet a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18 b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12 c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6 d = chunk & 63; // 63 = 2^6 - 1 // Convert the raw binary segments to the appropriate ASCII encoding base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]; } // Deal with the remaining bytes and padding if (byteRemainder == 1) { chunk = bytes[mainLength]; a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2 // Set the 4 least significant bits to zero b = (chunk & 3) << 4; // 3 = 2^2 - 1 base64 += encodings[a] + encodings[b] + '=='; } else if (byteRemainder == 2) { chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]; a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10 b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4 // Set the 2 least significant bits to zero c = (chunk & 15) << 2; // 15 = 2^4 - 1 base64 += encodings[a] + encodings[b] + encodings[c] + '='; } return base64; } static base64Decode(base64Str) { const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; // get last chars to see if are valid const lkey1 = _keyStr.indexOf(base64Str.charAt(base64Str.length - 1)); const lkey2 = _keyStr.indexOf(base64Str.charAt(base64Str.length - 2)); let bytes = (base64Str.length / 4) * 3; if (lkey1 == 64) bytes--; // padding chars, so skip if (lkey2 == 64) bytes--; // padding chars, so skip let byteArray = []; let chr1, chr2, chr3; let enc1, enc2, enc3, enc4; let i = 0; let j = 0; base64Str = base64Str.replace(/[^A-Za-z0-9\+\/\=]/g, ""); for (i = 0; i < bytes; i += 3) { //get the 3 octects in 4 ascii chars enc1 = _keyStr.indexOf(base64Str.charAt(j++)); enc2 = _keyStr.indexOf(base64Str.charAt(j++)); enc3 = _keyStr.indexOf(base64Str.charAt(j++)); enc4 = _keyStr.indexOf(base64Str.charAt(j++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; byteArray[i] = chr1; if (enc3 != 64) byteArray[i + 1] = chr2; if (enc4 != 64) byteArray[i + 2] = chr3; } return byteArray; } }