'use strict'; /** * btoa() as defined by the HTML5 spec, which mostly just references RFC4648. */ function btoa(s) { var i; // String conversion as required by WebIDL. s = String(s); // "The btoa() method must throw an INVALID_CHARACTER_ERR exception if the // method's first argument contains any character whose code point is // greater than U+00FF." for (i = 0; i < s.length; i++) { if (s.charCodeAt(i) > 255) { return null; } } var out = ''; for (i = 0; i < s.length; i += 3) { var groupsOfSix = [undefined, undefined, undefined, undefined]; groupsOfSix[0] = s.charCodeAt(i) >> 2; groupsOfSix[1] = (s.charCodeAt(i) & 0x03) << 4; if (s.length > i + 1) { groupsOfSix[1] |= s.charCodeAt(i + 1) >> 4; groupsOfSix[2] = (s.charCodeAt(i + 1) & 0x0f) << 2; } if (s.length > i + 2) { groupsOfSix[2] |= s.charCodeAt(i + 2) >> 6; groupsOfSix[3] = s.charCodeAt(i + 2) & 0x3f; } for (var j = 0; j < groupsOfSix.length; j++) { if (typeof groupsOfSix[j] == 'undefined') { out += '='; } else { out += btoaLookup(groupsOfSix[j]); } } } return out; } /** * Lookup table for btoa(), which converts a six-bit number into the * corresponding ASCII character. */ function btoaLookup(idx) { if (idx < 26) { return String.fromCharCode(idx + 'A'.charCodeAt(0)); } if (idx < 52) { return String.fromCharCode(idx - 26 + 'a'.charCodeAt(0)); } if (idx < 62) { return String.fromCharCode(idx - 52 + '0'.charCodeAt(0)); } if (idx == 62) { return '+'; } if (idx == 63) { return '/'; } // Throw INVALID_CHARACTER_ERR exception here -- won't be hit in the tests. } module.exports = btoa;