export function encodeBase64(bytes) { return encodeBase64_internal(bytes, base64Alphabet, EncodingPadding.Include); } export function encodeBase64NoPadding(bytes) { return encodeBase64_internal(bytes, base64Alphabet, EncodingPadding.None); } export function encodeBase64url(bytes) { return encodeBase64_internal(bytes, base64urlAlphabet, EncodingPadding.Include); } export function encodeBase64urlNoPadding(bytes) { return encodeBase64_internal(bytes, base64urlAlphabet, EncodingPadding.None); } function encodeBase64_internal(bytes, alphabet, padding) { let result = ""; for (let i = 0; i < bytes.byteLength; i += 3) { let buffer = 0; let bufferBitSize = 0; for (let j = 0; j < 3 && i + j < bytes.byteLength; j++) { buffer = (buffer << 8) | bytes[i + j]; bufferBitSize += 8; } for (let j = 0; j < 4; j++) { if (bufferBitSize >= 6) { result += alphabet[(buffer >> (bufferBitSize - 6)) & 0x3f]; bufferBitSize -= 6; } else if (bufferBitSize > 0) { result += alphabet[(buffer << (6 - bufferBitSize)) & 0x3f]; bufferBitSize = 0; } else if (padding === EncodingPadding.Include) { result += "="; } } } return result; } const base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const base64urlAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; export function decodeBase64(encoded) { return decodeBase64_internal(encoded, base64DecodeMap, DecodingPadding.Required); } export function decodeBase64IgnorePadding(encoded) { return decodeBase64_internal(encoded, base64DecodeMap, DecodingPadding.Ignore); } export function decodeBase64url(encoded) { return decodeBase64_internal(encoded, base64urlDecodeMap, DecodingPadding.Required); } export function decodeBase64urlIgnorePadding(encoded) { return decodeBase64_internal(encoded, base64urlDecodeMap, DecodingPadding.Ignore); } function decodeBase64_internal(encoded, decodeMap, padding) { const result = new Uint8Array(Math.ceil(encoded.length / 4) * 3); let totalBytes = 0; for (let i = 0; i < encoded.length; i += 4) { let chunk = 0; let bitsRead = 0; for (let j = 0; j < 4; j++) { if (padding === DecodingPadding.Required && encoded[i + j] === "=") { continue; } if (padding === DecodingPadding.Ignore && (i + j >= encoded.length || encoded[i + j] === "=")) { continue; } if (j > 0 && encoded[i + j - 1] === "=") { throw new Error("Invalid padding"); } if (!(encoded[i + j] in decodeMap)) { throw new Error("Invalid character"); } chunk |= decodeMap[encoded[i + j]] << ((3 - j) * 6); bitsRead += 6; } if (bitsRead < 24) { let unused; if (bitsRead === 12) { unused = chunk & 0xffff; } else if (bitsRead === 18) { unused = chunk & 0xff; } else { throw new Error("Invalid padding"); } if (unused !== 0) { throw new Error("Invalid padding"); } } const byteLength = Math.floor(bitsRead / 8); for (let i = 0; i < byteLength; i++) { result[totalBytes] = (chunk >> (16 - i * 8)) & 0xff; totalBytes++; } } return result.slice(0, totalBytes); } var EncodingPadding; (function (EncodingPadding) { EncodingPadding[EncodingPadding["Include"] = 0] = "Include"; EncodingPadding[EncodingPadding["None"] = 1] = "None"; })(EncodingPadding || (EncodingPadding = {})); var DecodingPadding; (function (DecodingPadding) { DecodingPadding[DecodingPadding["Required"] = 0] = "Required"; DecodingPadding[DecodingPadding["Ignore"] = 1] = "Ignore"; })(DecodingPadding || (DecodingPadding = {})); const base64DecodeMap = { "0": 52, "1": 53, "2": 54, "3": 55, "4": 56, "5": 57, "6": 58, "7": 59, "8": 60, "9": 61, A: 0, B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7, I: 8, J: 9, K: 10, L: 11, M: 12, N: 13, O: 14, P: 15, Q: 16, R: 17, S: 18, T: 19, U: 20, V: 21, W: 22, X: 23, Y: 24, Z: 25, a: 26, b: 27, c: 28, d: 29, e: 30, f: 31, g: 32, h: 33, i: 34, j: 35, k: 36, l: 37, m: 38, n: 39, o: 40, p: 41, q: 42, r: 43, s: 44, t: 45, u: 46, v: 47, w: 48, x: 49, y: 50, z: 51, "+": 62, "/": 63 }; const base64urlDecodeMap = { "0": 52, "1": 53, "2": 54, "3": 55, "4": 56, "5": 57, "6": 58, "7": 59, "8": 60, "9": 61, A: 0, B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7, I: 8, J: 9, K: 10, L: 11, M: 12, N: 13, O: 14, P: 15, Q: 16, R: 17, S: 18, T: 19, U: 20, V: 21, W: 22, X: 23, Y: 24, Z: 25, a: 26, b: 27, c: 28, d: 29, e: 30, f: 31, g: 32, h: 33, i: 34, j: 35, k: 36, l: 37, m: 38, n: 39, o: 40, p: 41, q: 42, r: 43, s: 44, t: 45, u: 46, v: 47, w: 48, x: 49, y: 50, z: 51, "-": 62, _: 63 };