export namespace Base64 { // adapted from https://gist.github.com/Juszczak/63e6d9e01decc850de03 /** * base64 encoding/decoding */ // @ts-ignore: decorator @lazy const PADCHAR = "="; // @ts-ignore: decorator @lazy const ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // @ts-ignore: decorator @lazy const ALPHAVALUES = StaticArray.fromArray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 63, 0, 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]); /** * Decode a base64-encoded string and return a Uint8Array. * @param s Base64 encoded string. * @example * ```ts * const signatureData = Base64.decode('IHhJwlD7P-o6x7L38den1MnumUhnYmNhTZhIUQQhezvEMf7rx89NbIIioNCIQSk1PQYdQ9mOI4-rDYiwO2pLvM4='); * ``` */ export function decode(s: string): Uint8Array { let i: u32, b10: u32; let pads = 0, imax = s.length as u32; if (imax == 0) { return new Uint8Array(0); } if (s.charAt(imax - 1) == PADCHAR) { pads = 1; if (s.charAt(imax - 2) == PADCHAR) { pads = 2; } imax -= 4; } let main_chunk = (imax / 4) * 3; let pad_size = pads > 0 ? 3 - pads : 0; let size = main_chunk + pad_size; let x = new Uint8Array(size), index = 0; for (i = 0; i < imax; i += 4) { b10 = (getByte64(s, i) << 18) | (getByte64(s, i + 1) << 12) | (getByte64(s, i + 2) << 6) | getByte64(s, i + 3); x[index++] = b10 >> 16; x[index++] = (b10 >> 8) & 255; x[index++] = b10 & 255; } switch (pads) { case 1: b10 = (getByte64(s, i) << 18) | (getByte64(s, i + 1) << 12) | (getByte64(s, i + 2) << 6); x[index++] = b10 >> 16; x[index++] = (b10 >> 8) & 255; break; case 2: b10 = (getByte64(s, i) << 18) | (getByte64(s, i + 1) << 12); x[index++] = b10 >> 16; break; } return x; } /** * Encode Uint8Array as a base64 string. * @param bytes Byte array of type Uint8Array. * @example * ```ts * const base64encodedStr = Base64.encode('Hello world!'); * ``` */ export function encode(bytes: Uint8Array): string { let i: i32, b10: u32; const extrabytes = (bytes.length % 3); let imax = bytes.length - extrabytes; const len = ((bytes.length / 3) as i32) * 4 + (extrabytes == 0 ? 0 : 4); //@ts-ignore let x = changetype(__new((len << 1), idof())); if (bytes.length == 0) { return ""; } let ptr = changetype(x) - 2; for (i = 0; i < imax; i += 3) { b10 = ((bytes[i] as u32) << 16) | ((bytes[i + 1] as u32) << 8) | (bytes[i + 2] as u32); store(ptr += 2, (ALPHA.charCodeAt(b10 >> 18) as u16)); store(ptr += 2, (ALPHA.charCodeAt(((b10 >> 12) & 63)) as u16)); store(ptr += 2, (ALPHA.charCodeAt(((b10 >> 6) & 63)) as u16)); store(ptr += 2, (ALPHA.charCodeAt((b10 & 63)) as u16)); } switch (bytes.length - imax) { case 1: b10 = (bytes[i] as u32) << 16; store(ptr += 2, ((ALPHA.charCodeAt(b10 >> 18)) as u16)); store(ptr += 2, ((ALPHA.charCodeAt((b10 >> 12) & 63)) as u16)); store(ptr += 2, ((PADCHAR.charCodeAt(0)) as u16)); store(ptr += 2, ((PADCHAR.charCodeAt(0)) as u16)); break; case 2: b10 = ((bytes[i] as u32) << 16) | ((bytes[i + 1] as u32) << 8); store(ptr += 2, ((ALPHA.charCodeAt(b10 >> 18)) as u16)); store(ptr += 2, ((ALPHA.charCodeAt((b10 >> 12) & 63)) as u16)); store(ptr += 2, ((ALPHA.charCodeAt((b10 >> 6) & 63)) as u16)); store(ptr += 2, ((PADCHAR.charCodeAt(0)) as u16)); break; } return x; } // @ts-ignore: decorator @inline function getByte64(s: string, i: u32): u32 { return ALPHAVALUES[s.charCodeAt(i)]; } }