UNPKG

5.83 kBJavaScriptView Raw
1"use strict";
2/**
3 * Slightly modernized version of [`base64-js`][1].
4 * Performance is slightly improved due to pre-allocating arrays.
5 *
6 * This version drops support for platforms that don't provide
7 * `Uint8Array` and `DataView`. Use the original in those cases.
8 *
9 * [1]: https://github.com/beatgammit/base64-js
10 * [2]: https://tools.ietf.org/html/rfc3986#section-2.3
11 */
12Object.defineProperty(exports, "__esModule", { value: true });
13exports.decode = exports.encode = exports.fromByteArray = exports.toByteArray = void 0;
14const b64lookup = [];
15const urlLookup = [];
16const revLookup = [];
17const CODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
18const CODE_B64 = CODE + '+/';
19const CODE_URL = CODE + '-_';
20const PAD = '=';
21const MAX_CHUNK_LENGTH = 16383; // must be multiple of 3
22for (let i = 0, len = CODE_B64.length; i < len; ++i) {
23 b64lookup[i] = CODE_B64[i];
24 urlLookup[i] = CODE_URL[i];
25 revLookup[CODE_B64.charCodeAt(i)] = i;
26}
27// Support decoding URL-safe base64 strings, as Node.js does.
28// See: https://en.wikipedia.org/wiki/Base64#URL_applications
29revLookup['-'.charCodeAt(0)] = 62;
30revLookup['_'.charCodeAt(0)] = 63;
31function getLens(b64) {
32 const len = b64.length;
33 // Trim off extra bytes after placeholder bytes are found
34 // See: https://github.com/beatgammit/base64-js/issues/42
35 let validLen = b64.indexOf(PAD);
36 if (validLen === -1)
37 validLen = len;
38 const placeHoldersLen = validLen === len
39 ? 0
40 : 4 - (validLen % 4);
41 return [validLen, placeHoldersLen];
42}
43function _byteLength(validLen, placeHoldersLen) {
44 return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen;
45}
46/**
47 * Takes a base 64 string and converts it to an array buffer.
48 * Accepts both regular Base64 and the URL-friendly variant,
49 * where `+` => `-`, `/` => `_`, and the padding character is omitted.
50 *
51 * @param str A Base64 string in either regular or URL-friendly representation.
52 * @returns The binary data as `Uint8Array`.
53 */
54function toByteArray(str) {
55 let tmp;
56 switch (str.length % 4) {
57 case 2:
58 str += "==";
59 break;
60 case 3:
61 str += "=";
62 break;
63 }
64 const [validLen, placeHoldersLen] = getLens(str);
65 const arr = new Uint8Array(_byteLength(validLen, placeHoldersLen));
66 let curByte = 0;
67 // if there are placeholders, only get up to the last complete 4 chars
68 const len = placeHoldersLen > 0
69 ? validLen - 4
70 : validLen;
71 let i;
72 for (i = 0; i < len; i += 4) {
73 tmp =
74 (revLookup[str.charCodeAt(i)] << 18) |
75 (revLookup[str.charCodeAt(i + 1)] << 12) |
76 (revLookup[str.charCodeAt(i + 2)] << 6) |
77 (revLookup[str.charCodeAt(i + 3)]);
78 arr[curByte++] = (tmp >> 16) & 0xff;
79 arr[curByte++] = (tmp >> 8) & 0xff;
80 arr[curByte++] = (tmp) & 0xff;
81 }
82 if (placeHoldersLen === 2) {
83 tmp =
84 (revLookup[str.charCodeAt(i)] << 2) |
85 (revLookup[str.charCodeAt(i + 1)] >> 4);
86 arr[curByte++] = tmp & 0xff;
87 }
88 if (placeHoldersLen === 1) {
89 tmp =
90 (revLookup[str.charCodeAt(i)] << 10) |
91 (revLookup[str.charCodeAt(i + 1)] << 4) |
92 (revLookup[str.charCodeAt(i + 2)] >> 2);
93 arr[curByte++] = (tmp >> 8) & 0xff;
94 arr[curByte++] = tmp & 0xff;
95 }
96 return arr;
97}
98exports.toByteArray = toByteArray;
99exports.decode = toByteArray;
100function tripletToBase64(lookup, num) {
101 return (lookup[num >> 18 & 0x3f] +
102 lookup[num >> 12 & 0x3f] +
103 lookup[num >> 6 & 0x3f] +
104 lookup[num & 0x3f]);
105}
106function encodeChunk(lookup, view, start, end) {
107 let tmp;
108 const output = new Array((end - start) / 3);
109 for (let i = start, j = 0; i < end; i += 3, j++) {
110 tmp =
111 ((view.getUint8(i) << 16) & 0xff0000) +
112 ((view.getUint8(i + 1) << 8) & 0x00ff00) +
113 (view.getUint8(i + 2) & 0x0000ff);
114 output[j] = tripletToBase64(lookup, tmp);
115 }
116 return output.join('');
117}
118const bs2dv = (bs) => bs instanceof ArrayBuffer
119 ? new DataView(bs)
120 : new DataView(bs.buffer, bs.byteOffset, bs.byteLength);
121/**
122 * Encodes binary data provided in an array buffer as a Base64 string.
123 * @param bufferSource The raw data to encode.
124 * @param urlFriendly Set to true to encode in a URL-friendly way.
125 * @returns The contents a Base64 string.
126 */
127function fromByteArray(bufferSource, urlFriendly = false) {
128 const view = bs2dv(bufferSource);
129 const len = view.byteLength;
130 const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
131 const len2 = len - extraBytes;
132 const parts = new Array(Math.floor(len2 / MAX_CHUNK_LENGTH) + Math.sign(extraBytes));
133 const lookup = urlFriendly ? urlLookup : b64lookup;
134 const pad = urlFriendly ? '' : PAD;
135 // Go through the array every three bytes, we'll deal with trailing stuff
136 // later
137 let j = 0;
138 for (let i = 0; i < len2; i += MAX_CHUNK_LENGTH) {
139 parts[j++] = encodeChunk(lookup, view, i, (i + MAX_CHUNK_LENGTH) > len2 ? len2 : (i + MAX_CHUNK_LENGTH));
140 }
141 // pad the end with zeros, but make sure to not forget the extra bytes
142 if (extraBytes === 1) {
143 const tmp = view.getUint8(len - 1);
144 parts[j] = (lookup[tmp >> 2] +
145 lookup[(tmp << 4) & 0x3f] +
146 pad + pad);
147 }
148 else if (extraBytes === 2) {
149 const tmp = (view.getUint8(len - 2) << 8) + view.getUint8(len - 1);
150 parts[j] = (lookup[tmp >> 10] +
151 lookup[(tmp >> 4) & 0x3f] +
152 lookup[(tmp << 2) & 0x3f] +
153 pad);
154 }
155 return parts.join('');
156}
157exports.fromByteArray = fromByteArray;
158exports.encode = fromByteArray;
159//# sourceMappingURL=base64-js.js.map
\No newline at end of file