/
WindowBase64.ts
95 lines (87 loc) · 2.07 KB
/
WindowBase64.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import DOMException from '../exception/DOMException';
import DOMExceptionNameEnum from '../exception/DOMExceptionNameEnum';
const base64list = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
/**
* Btoa.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/btoa.
*
* @param data
*/
export const btoa = (data: unknown): string => {
const str = (<string>data).toString();
if (/[^\u0000-\u00ff]/.test(str)) {
throw new DOMException(
"Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.",
DOMExceptionNameEnum.invalidCharacterError
);
}
let t = '';
let p = -6;
let a = 0;
let i = 0;
let v = 0;
let c;
while (i < str.length || p > -6) {
if (p < 0) {
if (i < str.length) {
c = str.charCodeAt(i++);
v += 8;
} else {
c = 0;
}
a = ((a & 255) << 8) | (c & 255);
p += 8;
}
t += base64list.charAt(v > 0 ? (a >> p) & 63 : 64);
p -= 6;
v -= 6;
}
return t;
};
/**
* Atob.
*
* Reference:
* https://infra.spec.whatwg.org/#forgiving-base64-encode.
* Https://html.spec.whatwg.org/multipage/webappapis.html#btoa.
*
* @param data
*/
export const atob = (data: unknown): string => {
const str = (<string>data).toString();
if (/[^\u0000-\u00ff]/.test(str)) {
throw new DOMException(
"Failed to execute 'atob' on 'Window': The string to be decoded contains characters outside of the Latin1 range.",
DOMExceptionNameEnum.invalidCharacterError
);
}
if (/[^A-Za-z\d+/=]/.test(str) || str.length % 4 == 1) {
throw new DOMException(
"Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.",
DOMExceptionNameEnum.invalidCharacterError
);
}
let t = '';
let p = -8;
let a = 0;
let c;
let d;
for (let i = 0; i < str.length; i++) {
if ((c = base64list.indexOf(str.charAt(i))) < 0) {
continue;
}
a = (a << 6) | (c & 63);
if ((p += 6) >= 0) {
d = (a >> p) & 255;
if (c !== 64) {
t += String.fromCharCode(d);
}
a &= 63;
p -= 8;
}
}
return t;
};
exports = { btoa: btoa, atob: atob };