From d73003d7053dd9598fc02b3106b414561edb1426 Mon Sep 17 00:00:00 2001 From: Devin Ivy Date: Mon, 19 May 2025 09:20:07 -0400 Subject: [PATCH] perf: improve rfc4648 base decoding --- src/bases/base.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/bases/base.ts b/src/bases/base.ts index 9b5c160c..6cc49f32 100644 --- a/src/bases/base.ts +++ b/src/bases/base.ts @@ -141,13 +141,7 @@ export function baseX ({ name, pref }) } -function decode (string: string, alphabet: string, bitsPerChar: number, name: string): Uint8Array { - // Build the character lookup table: - const codes: Record = {} - for (let i = 0; i < alphabet.length; ++i) { - codes[alphabet[i]] = i - } - +function decode (string: string, alphabetIdx: Record, bitsPerChar: number, name: string): Uint8Array { // Count the padding bytes: let end = string.length while (string[end - 1] === '=') { @@ -163,7 +157,7 @@ function decode (string: string, alphabet: string, bitsPerChar: number, name: st let written = 0 // Next byte to write for (let i = 0; i < end; ++i) { // Read one character from the string: - const value = codes[string[i]] + const value = alphabetIdx[string[i]] if (value === undefined) { throw new SyntaxError(`Non-${name} character`) } @@ -221,10 +215,20 @@ function encode (data: Uint8Array, alphabet: string, bitsPerChar: number): strin return out } +function createAlphabetIdx (alphabet: string): Record { + // Build the character lookup table: + const alphabetIdx: Record = {} + for (let i = 0; i < alphabet.length; ++i) { + alphabetIdx[alphabet[i]] = i + } + return alphabetIdx +} + /** * RFC4648 Factory */ export function rfc4648 ({ name, prefix, bitsPerChar, alphabet }: { name: Base, prefix: Prefix, bitsPerChar: number, alphabet: string }): Codec { + const alphabetIdx = createAlphabetIdx(alphabet) return from({ prefix, name, @@ -232,7 +236,7 @@ export function rfc4648 ({ name, pr return encode(input, alphabet, bitsPerChar) }, decode (input: string): Uint8Array { - return decode(input, alphabet, bitsPerChar, name) + return decode(input, alphabetIdx, bitsPerChar, name) } }) }