123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true,
- });
- exports.base64 = base64;
- exports.unbase64 = unbase64;
- function base64(input) {
- const utf8Array = stringToUTF8Array(input);
- let result = '';
- const length = utf8Array.length;
- const rest = length % 3;
- for (let i = 0; i < length - rest; i += 3) {
- const a = utf8Array[i];
- const b = utf8Array[i + 1];
- const c = utf8Array[i + 2];
- result += first6Bits(a);
- result += last2BitsAndFirst4Bits(a, b);
- result += last4BitsAndFirst2Bits(b, c);
- result += last6Bits(c);
- }
- if (rest === 1) {
- const a = utf8Array[length - 1];
- result += first6Bits(a) + last2BitsAndFirst4Bits(a, 0) + '==';
- } else if (rest === 2) {
- const a = utf8Array[length - 2];
- const b = utf8Array[length - 1];
- result +=
- first6Bits(a) +
- last2BitsAndFirst4Bits(a, b) +
- last4BitsAndFirst2Bits(b, 0) +
- '=';
- }
- return result;
- }
- function first6Bits(a) {
- return toBase64Char((a >> 2) & 63);
- }
- function last2BitsAndFirst4Bits(a, b) {
- return toBase64Char(((a << 4) | (b >> 4)) & 63);
- }
- function last4BitsAndFirst2Bits(b, c) {
- return toBase64Char(((b << 2) | (c >> 6)) & 63);
- }
- function last6Bits(c) {
- return toBase64Char(c & 63);
- }
- function unbase64(input) {
- const utf8Array = [];
- for (let i = 0; i < input.length; i += 4) {
- const a = fromBase64Char(input[i]);
- const b = fromBase64Char(input[i + 1]);
- const c = fromBase64Char(input[i + 2]);
- const d = fromBase64Char(input[i + 3]);
- if (a === -1 || b === -1 || c === -1 || d === -1) {
- /*
- * Previously we used Node's API for parsing Base64 and following code
- * Buffer.from(i, 'utf8').toString('base64')
- * That silently ignored incorrect input and returned empty string instead
- * Let's keep this behaviour for a time being and hopefully fix it in the future.
- */
- return '';
- }
- const bitmap24 = (a << 18) | (b << 12) | (c << 6) | d;
- utf8Array.push((bitmap24 >> 16) & 255);
- utf8Array.push((bitmap24 >> 8) & 255);
- utf8Array.push(bitmap24 & 255);
- }
- let paddingIndex = input.length - 1;
- while (input[paddingIndex] === '=') {
- --paddingIndex;
- utf8Array.pop();
- }
- return utf8ArrayToString(utf8Array);
- }
- const b64CharacterSet =
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
- function toBase64Char(bitMap6) {
- return b64CharacterSet.charAt(bitMap6);
- }
- function fromBase64Char(base64Char) {
- if (base64Char === undefined) {
- return -1;
- }
- return base64Char === '=' ? 0 : b64CharacterSet.indexOf(base64Char);
- }
- function stringToUTF8Array(input) {
- const result = [];
- for (const utfChar of input) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const code = utfChar.codePointAt(0);
- if (code < 0x80) {
- result.push(code);
- } else if (code < 0x800) {
- result.push(0xc0 | (code >> 6));
- result.push(0x80 | (code & 0x3f));
- } else if (code < 0x10000) {
- result.push(0xe0 | (code >> 12));
- result.push(0x80 | ((code >> 6) & 0x3f));
- result.push(0x80 | (code & 0x3f));
- } else {
- result.push(0xf0 | (code >> 18));
- result.push(0x80 | ((code >> 12) & 0x3f));
- result.push(0x80 | ((code >> 6) & 0x3f));
- result.push(0x80 | (code & 0x3f));
- }
- }
- return result;
- }
- function utf8ArrayToString(input) {
- let result = '';
- for (let i = 0; i < input.length; ) {
- const a = input[i++];
- if ((a & 0x80) === 0) {
- result += fromCodePoint(a);
- continue;
- }
- const b = input[i++];
- if ((a & 0xe0) === 0xc0) {
- result += fromCodePoint(((a & 0x1f) << 6) | (b & 0x3f));
- continue;
- }
- const c = input[i++];
- if ((a & 0xf0) === 0xe0) {
- result += fromCodePoint(
- ((a & 0x0f) << 12) | ((b & 0x3f) << 6) | (c & 0x3f),
- );
- continue;
- }
- const d = input[i++];
- result += fromCodePoint(
- ((a & 0x07) << 18) | ((b & 0x3f) << 12) | ((c & 0x3f) << 6) | (d & 0x3f),
- );
- }
- return result;
- }
- function fromCodePoint(code) {
- if (code > 0x10ffff) {
- /*
- * Previously we used Node's API for parsing Base64 and following code
- * Buffer.from(i, 'base64').toString('utf8')
- * That silently ignored incorrect input and returned empty string instead
- * Let's keep this behaviour for a time being and hopefully fix it in the future.
- */
- return '';
- }
- return String.fromCodePoint(code);
- }
|