2022-06-24 17:58:12 -04:00
|
|
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
|
|
|
|
/* The JS world is still in the stone age. We're in 2022 and we still don't
|
|
|
|
* have the technology to correctly base64-encode a UTF-8 string. Can't wait
|
|
|
|
* the next industrial revolution.
|
|
|
|
*
|
|
|
|
* For more info, see:
|
|
|
|
* https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
|
|
|
|
*/
|
|
|
|
export function encode(data) {
|
|
|
|
if (!window.TextEncoder) {
|
|
|
|
return btoa(data);
|
|
|
|
}
|
|
|
|
|
2024-09-28 16:07:39 -04:00
|
|
|
let encoder = new TextEncoder();
|
|
|
|
let bytes = encoder.encode(data);
|
2022-06-24 17:58:12 -04:00
|
|
|
|
2024-09-28 16:07:39 -04:00
|
|
|
let trailing = bytes.length % 3;
|
|
|
|
let out = "";
|
|
|
|
for (let i = 0; i < bytes.length - trailing; i += 3) {
|
|
|
|
let u24 = (bytes[i] << 16) + (bytes[i + 1] << 8) + bytes[i + 2];
|
2022-06-24 17:58:12 -04:00
|
|
|
out += alphabet[(u24 >> 18) & 0x3F];
|
|
|
|
out += alphabet[(u24 >> 12) & 0x3F];
|
|
|
|
out += alphabet[(u24 >> 6) & 0x3F];
|
|
|
|
out += alphabet[u24 & 0x3F];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (trailing == 1) {
|
2024-09-28 16:07:39 -04:00
|
|
|
let u8 = bytes[bytes.length - 1];
|
2022-06-24 17:58:12 -04:00
|
|
|
out += alphabet[u8 >> 2];
|
|
|
|
out += alphabet[(u8 << 4) & 0x3F];
|
|
|
|
out += "==";
|
|
|
|
} else if (trailing == 2) {
|
2024-09-28 16:07:39 -04:00
|
|
|
let u16 = (bytes[bytes.length - 2] << 8) + bytes[bytes.length - 1];
|
2022-06-24 17:58:12 -04:00
|
|
|
out += alphabet[u16 >> 10];
|
|
|
|
out += alphabet[(u16 >> 4) & 0x3F];
|
|
|
|
out += alphabet[(u16 << 2) & 0x3F];
|
|
|
|
out += "=";
|
|
|
|
}
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|