const internalBase64Pattern = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/ const internalNormalizeBase64 = (input: string): string => { return input.replaceAll(/\s+/g, "") } /** * @description 判断输入是否为合法的 Base64 字符串。 * * @example * ``` * // Expect: true * const example1 = isBase64("aGVsbG8=") * // Expect: false * const example2 = isBase64("abc") * ``` */ export const isBase64 = (input: string): boolean => { const normalizedInput = internalNormalizeBase64(input) return internalBase64Pattern.test(normalizedInput) } const internalAssertValidBase64 = (input: string): void => { if (internalBase64Pattern.test(input) === false) { throw new TypeError("Invalid Base64 input") } } /** * @description 断言输入是合法的 Base64 字符串。 * * @example * ``` * const example1 = assertBase64("aGVsbG8=") * // Expect: undefined * * // Expect: throws TypeError * const example2 = () => assertBase64("abc") * ``` * * @throws { TypeError } When input is not valid Base64 */ export const assertBase64 = (input: string): void => { const normalizedInput = internalNormalizeBase64(input) internalAssertValidBase64(normalizedInput) } const internalStringToBase64ByBrowserApi = (input: string): string => { const bytes = new TextEncoder().encode(input) let binaryString = "" bytes.forEach((byte) => { binaryString = binaryString + String.fromCodePoint(byte) }) return btoa(binaryString) } /** * @description 将 UTF-8 字符串转换为 Base64 字符串。 * * @example * ``` * // Expect: "aGVsbG8=" * const example1 = stringToBase64("hello") * // Expect: "5L2g5aW9" * const example2 = stringToBase64("你好") * ``` */ export const stringToBase64 = (input: string): string => { if (typeof Buffer !== "undefined") { return Buffer.from(input, "utf8").toString("base64") } if (typeof btoa !== "undefined") { return internalStringToBase64ByBrowserApi(input) } throw new Error("No Base64 runtime support found") } const internalBase64ToStringByBrowserApi = (input: string): string => { const binaryString = atob(input) const bytes = Uint8Array.from(binaryString, (char) => char.codePointAt(0) ?? 0) return new TextDecoder().decode(bytes) } /** * @description 将合法的 Base64 字符串转换为 UTF-8 字符串。 * * @example * ``` * // Expect: "hello" * const example1 = base64ToString("aGVsbG8=") * // Expect: "你好" * const example2 = base64ToString("5L2g5aW9") * ``` */ export const base64ToString = (input: string): string => { const normalizedInput = internalNormalizeBase64(input) internalAssertValidBase64(normalizedInput) if (typeof Buffer !== "undefined") { return Buffer.from(normalizedInput, "base64").toString("utf8") } if (typeof atob !== "undefined") { return internalBase64ToStringByBrowserApi(normalizedInput) } throw new Error("No Base64 runtime support found") }