UNPKG

1.69 kBJavaScriptView Raw
1"use strict";
2
3/**
4 * btoa() as defined by the HTML and Infra specs, which mostly just references
5 * RFC 4648.
6 */
7function btoa(s) {
8 if (arguments.length === 0) {
9 throw new TypeError("1 argument required, but only 0 present.");
10 }
11
12 let i;
13 // String conversion as required by Web IDL.
14 s = `${s}`;
15 // "The btoa() method must throw an "InvalidCharacterError" DOMException if
16 // data contains any character whose code point is greater than U+00FF."
17 for (i = 0; i < s.length; i++) {
18 if (s.charCodeAt(i) > 255) {
19 return null;
20 }
21 }
22 let out = "";
23 for (i = 0; i < s.length; i += 3) {
24 const groupsOfSix = [undefined, undefined, undefined, undefined];
25 groupsOfSix[0] = s.charCodeAt(i) >> 2;
26 groupsOfSix[1] = (s.charCodeAt(i) & 0x03) << 4;
27 if (s.length > i + 1) {
28 groupsOfSix[1] |= s.charCodeAt(i + 1) >> 4;
29 groupsOfSix[2] = (s.charCodeAt(i + 1) & 0x0f) << 2;
30 }
31 if (s.length > i + 2) {
32 groupsOfSix[2] |= s.charCodeAt(i + 2) >> 6;
33 groupsOfSix[3] = s.charCodeAt(i + 2) & 0x3f;
34 }
35 for (let j = 0; j < groupsOfSix.length; j++) {
36 if (typeof groupsOfSix[j] === "undefined") {
37 out += "=";
38 } else {
39 out += btoaLookup(groupsOfSix[j]);
40 }
41 }
42 }
43 return out;
44}
45
46/**
47 * Lookup table for btoa(), which converts a six-bit number into the
48 * corresponding ASCII character.
49 */
50const keystr =
51 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
52
53function btoaLookup(index) {
54 if (index >= 0 && index < 64) {
55 return keystr[index];
56 }
57
58 // Throw INVALID_CHARACTER_ERR exception here -- won't be hit in the tests.
59 return undefined;
60}
61
62module.exports = btoa;