Skip to content

Commit 900b5f6

Browse files
authored
fix(perf): improve rfc4648 base decoding (#323)
1 parent c9abde0 commit 900b5f6

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

src/bases/base.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,7 @@ export function baseX <Base extends string, Prefix extends string> ({ name, pref
141141
})
142142
}
143143

144-
function decode (string: string, alphabet: string, bitsPerChar: number, name: string): Uint8Array {
145-
// Build the character lookup table:
146-
const codes: Record<string, number> = {}
147-
for (let i = 0; i < alphabet.length; ++i) {
148-
codes[alphabet[i]] = i
149-
}
150-
144+
function decode (string: string, alphabetIdx: Record<string, number>, bitsPerChar: number, name: string): Uint8Array {
151145
// Count the padding bytes:
152146
let end = string.length
153147
while (string[end - 1] === '=') {
@@ -163,7 +157,7 @@ function decode (string: string, alphabet: string, bitsPerChar: number, name: st
163157
let written = 0 // Next byte to write
164158
for (let i = 0; i < end; ++i) {
165159
// Read one character from the string:
166-
const value = codes[string[i]]
160+
const value = alphabetIdx[string[i]]
167161
if (value === undefined) {
168162
throw new SyntaxError(`Non-${name} character`)
169163
}
@@ -221,18 +215,28 @@ function encode (data: Uint8Array, alphabet: string, bitsPerChar: number): strin
221215
return out
222216
}
223217

218+
function createAlphabetIdx (alphabet: string): Record<string, number> {
219+
// Build the character lookup table:
220+
const alphabetIdx: Record<string, number> = {}
221+
for (let i = 0; i < alphabet.length; ++i) {
222+
alphabetIdx[alphabet[i]] = i
223+
}
224+
return alphabetIdx
225+
}
226+
224227
/**
225228
* RFC4648 Factory
226229
*/
227230
export function rfc4648 <Base extends string, Prefix extends string> ({ name, prefix, bitsPerChar, alphabet }: { name: Base, prefix: Prefix, bitsPerChar: number, alphabet: string }): Codec<Base, Prefix> {
231+
const alphabetIdx = createAlphabetIdx(alphabet)
228232
return from({
229233
prefix,
230234
name,
231235
encode (input: Uint8Array): string {
232236
return encode(input, alphabet, bitsPerChar)
233237
},
234238
decode (input: string): Uint8Array {
235-
return decode(input, alphabet, bitsPerChar, name)
239+
return decode(input, alphabetIdx, bitsPerChar, name)
236240
}
237241
})
238242
}

0 commit comments

Comments
 (0)