1 | var alphabetByEncoding = {};
|
2 | var alphabetByValue = new Array(64);
|
3 | for (var i = 0, start = "A".charCodeAt(0), limit = "Z".charCodeAt(0); i + start <= limit; i++) {
|
4 | var char = String.fromCharCode(i + start);
|
5 | alphabetByEncoding[char] = i;
|
6 | alphabetByValue[i] = char;
|
7 | }
|
8 | for (var i = 0, start = "a".charCodeAt(0), limit = "z".charCodeAt(0); i + start <= limit; i++) {
|
9 | var char = String.fromCharCode(i + start);
|
10 | var index = i + 26;
|
11 | alphabetByEncoding[char] = index;
|
12 | alphabetByValue[index] = char;
|
13 | }
|
14 | for (var i = 0; i < 10; i++) {
|
15 | alphabetByEncoding[i.toString(10)] = i + 52;
|
16 | var char = i.toString(10);
|
17 | var index = i + 52;
|
18 | alphabetByEncoding[char] = index;
|
19 | alphabetByValue[index] = char;
|
20 | }
|
21 | alphabetByEncoding["+"] = 62;
|
22 | alphabetByValue[62] = "+";
|
23 | alphabetByEncoding["/"] = 63;
|
24 | alphabetByValue[63] = "/";
|
25 | var bitsPerLetter = 6;
|
26 | var bitsPerByte = 8;
|
27 | var maxLetterValue = 63;
|
28 | export function fromBase64(input) {
|
29 | var totalByteLength = (input.length / 4) * 3;
|
30 | if (input.slice(-2) === "==") {
|
31 | totalByteLength -= 2;
|
32 | }
|
33 | else if (input.slice(-1) === "=") {
|
34 | totalByteLength--;
|
35 | }
|
36 | var out = new ArrayBuffer(totalByteLength);
|
37 | var dataView = new DataView(out);
|
38 | for (var i = 0; i < input.length; i += 4) {
|
39 | var bits = 0;
|
40 | var bitLength = 0;
|
41 | for (var j = i, limit = i + 3; j <= limit; j++) {
|
42 | if (input[j] !== "=") {
|
43 | if (!(input[j] in alphabetByEncoding)) {
|
44 | throw new TypeError("Invalid character ".concat(input[j], " in base64 string."));
|
45 | }
|
46 | bits |= alphabetByEncoding[input[j]] << ((limit - j) * bitsPerLetter);
|
47 | bitLength += bitsPerLetter;
|
48 | }
|
49 | else {
|
50 | bits >>= bitsPerLetter;
|
51 | }
|
52 | }
|
53 | var chunkOffset = (i / 4) * 3;
|
54 | bits >>= bitLength % bitsPerByte;
|
55 | var byteLength = Math.floor(bitLength / bitsPerByte);
|
56 | for (var k = 0; k < byteLength; k++) {
|
57 | var offset = (byteLength - k - 1) * bitsPerByte;
|
58 | dataView.setUint8(chunkOffset + k, (bits & (255 << offset)) >> offset);
|
59 | }
|
60 | }
|
61 | return new Uint8Array(out);
|
62 | }
|
63 | export function toBase64(input) {
|
64 | var str = "";
|
65 | for (var i = 0; i < input.length; i += 3) {
|
66 | var bits = 0;
|
67 | var bitLength = 0;
|
68 | for (var j = i, limit = Math.min(i + 3, input.length); j < limit; j++) {
|
69 | bits |= input[j] << ((limit - j - 1) * bitsPerByte);
|
70 | bitLength += bitsPerByte;
|
71 | }
|
72 | var bitClusterCount = Math.ceil(bitLength / bitsPerLetter);
|
73 | bits <<= bitClusterCount * bitsPerLetter - bitLength;
|
74 | for (var k = 1; k <= bitClusterCount; k++) {
|
75 | var offset = (bitClusterCount - k) * bitsPerLetter;
|
76 | str += alphabetByValue[(bits & (maxLetterValue << offset)) >> offset];
|
77 | }
|
78 | str += "==".slice(0, 4 - bitClusterCount);
|
79 | }
|
80 | return str;
|
81 | }
|