;(function (root, factory) { if (typeof exports === "object") { // CommonJS module.exports = exports = factory(require("./core")); } else if (typeof define === "function" && define.amd) { // AMD define(["./core"], factory); } else { // Global (browser) factory(root.CryptoJS); } }(this, function (CryptoJS) { (function () { // Shortcuts var C = CryptoJS; var C_lib = C.lib; var WordArray = C_lib.WordArray; var C_enc = C.enc; /** * Base64url encoding strategy. */ var Base64url = C_enc.Base64url = { /** * Converts a word array to a Base64url string. * * @param {WordArray} wordArray The word array. * * @param {boolean} urlSafe Whether to use url safe * * @return {string} The Base64url string. * * @static * * @example * * var base64String = CryptoJS.enc.Base64url.stringify(wordArray); */ stringify: function (wordArray, urlSafe=true) { // Shortcuts var words = wordArray.words; var sigBytes = wordArray.sigBytes; var map = urlSafe ? this._safe_map : this._map; // Clamp excess bits wordArray.clamp(); // Convert var base64Chars = []; for (var i = 0; i < sigBytes; i += 3) { var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; var triplet = (byte1 << 16) | (byte2 << 8) | byte3; for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); } } // Add padding var paddingChar = map.charAt(64); if (paddingChar) { while (base64Chars.length % 4) { base64Chars.push(paddingChar); } } return base64Chars.join(''); }, /** * Converts a Base64url string to a word array. * * @param {string} base64Str The Base64url string. * * @param {boolean} urlSafe Whether to use url safe * * @return {WordArray} The word array. * * @static * * @example * * var wordArray = CryptoJS.enc.Base64url.parse(base64String); */ parse: function (base64Str, urlSafe=true) { // Shortcuts var base64StrLength = base64Str.length; var map = urlSafe ? this._safe_map : this._map; var reverseMap = this._reverseMap; if (!reverseMap) { reverseMap = this._reverseMap = []; for (var j = 0; j < map.length; j++) { reverseMap[map.charCodeAt(j)] = j; } } // Ignore padding var paddingChar = map.charAt(64); if (paddingChar) { var paddingIndex = base64Str.indexOf(paddingChar); if (paddingIndex !== -1) { base64StrLength = paddingIndex; } } // Convert return parseLoop(base64Str, base64StrLength, reverseMap); }, _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', _safe_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', }; function parseLoop(base64Str, base64StrLength, reverseMap) { var words = []; var nBytes = 0; for (var i = 0; i < base64StrLength; i++) { if (i % 4) { var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); var bitsCombined = bits1 | bits2; words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8); nBytes++; } } return WordArray.create(words, nBytes); } }()); return CryptoJS.enc.Base64url; }));