diff --git a/src/basex.mjs b/src/basex.mjs index 58132ee92f18e0935d196c451f1b9e5d6e3f39e4..412d325442eb73a63db4845ae53df84b7e13a35c 100644 --- a/src/basex.mjs +++ b/src/basex.mjs @@ -4,67 +4,74 @@ export const b58 = basex(B58_ALPHABET); export const b16 = basex('0123456789abcdef'); export default basex; export function basex(ALPHABET) { - const ALPHABET_MAP = {}; - const BASE = ALPHABET.length; - const LEADER = ALPHABET.charAt(0); + const config = { + ALPHABET_MAP: {}, + BASE: ALPHABET.length, + LEADER: ALPHABET.charAt(0), + ALPHABET: ALPHABET + } // Pre-compute lookup table - for (let z = 0; z < ALPHABET.length; z++) { - const x = ALPHABET.charAt(z); - if (ALPHABET_MAP[x] !== undefined) throw new TypeError(x + ' is ambiguous'); - ALPHABET_MAP[x] = z; + for (let z = 0; z < config.ALPHABET.length; z++) { + const x = config.ALPHABET.charAt(z); + if (config.ALPHABET_MAP[x] !== undefined) throw new TypeError(x + ' is ambiguous'); + config.ALPHABET_MAP[x] = z; } - function encode(source) { - if (source.length === 0) return ''; - const digits = [0]; - for (let carry of source) { - for (let j = 0; j < digits.length; ++j) { - carry += digits[j] << 8; - digits[j] = carry % BASE; - carry = (carry / BASE) | 0; // eslint-disable-line unicorn/prefer-math-trunc - } + return { + encode:source=>encode(source,config), + decodeUnsafe:string=>decodeUnsafe(string,config), + decode:string=>decode(string,config) + }; +} - while (carry > 0) { - digits.push(carry % BASE); - carry = (carry / BASE) | 0; // eslint-disable-line unicorn/prefer-math-trunc - } +function encode(source, config) { + if (source.length === 0) return ''; + const digits = [0]; + for (let carry of source) { + for (let j = 0; j < digits.length; ++j) { + carry += digits[j] << 8; + digits[j] = carry % config.BASE; + carry = (carry / config.BASE) | 0; // eslint-disable-line unicorn/prefer-math-trunc } - let string = ''; - for (let k = 0; source[k] === 0 && k < source.length - 1; ++k) string += LEADER; // Deal with leading zeros - for (let q = digits.length - 1; q >= 0; --q) string += ALPHABET[digits[q]]; // Convert digits to a string - return string; + while (carry > 0) { + digits.push(carry % config.BASE); + carry = (carry / config.BASE) | 0; // eslint-disable-line unicorn/prefer-math-trunc + } } - function decodeUnsafe(string) { - if (typeof string !== 'string') throw new TypeError('Expected String'); - if (string.length === 0) return new Uint8Array(0); - const bytes = [0]; - for (const chr of string) { - const value = ALPHABET_MAP[chr]; - if (value === undefined) return; - let carry = value; - for (let j = 0; j < bytes.length; ++j) { - carry += bytes[j] * BASE; - bytes[j] = carry & 0xff; - carry >>= 8; - } + let string = ''; + for (let k = 0; source[k] === 0 && k < source.length - 1; ++k) string += config.LEADER; // Deal with leading zeros + for (let q = digits.length - 1; q >= 0; --q) string += config.ALPHABET[digits[q]]; // Convert digits to a string + return string; +} - while (carry > 0) { - bytes.push(carry & 0xff); - carry >>= 8; - } +function decodeUnsafe(string, config) { + if (typeof string !== 'string') throw new TypeError('Expected String'); + if (string.length === 0) return new Uint8Array(0); + const bytes = [0]; + for (const chr of string) { + const value = config.ALPHABET_MAP[chr]; + if (value === undefined) return; + let carry = value; + for (let j = 0; j < bytes.length; ++j) { + carry += bytes[j] * config.BASE; + bytes[j] = carry & 0xff; + carry >>= 8; } - for (let k = 0; string[k] === LEADER && k < string.length - 1; ++k) bytes.push(0); // Deal with leading zeros - return new Uint8Array(bytes.reverse()); + while (carry > 0) { + bytes.push(carry & 0xff); + carry >>= 8; + } } - function decode(string) { - const buffer = decodeUnsafe(string); - if (buffer) return buffer; - throw new Error('Non-base' + BASE + ' character'); - } + for (let k = 0; string[k] === config.LEADER && k < string.length - 1; ++k) bytes.push(0); // Deal with leading zeros + return new Uint8Array(bytes.reverse()); +} - return {encode, decodeUnsafe, decode}; +function decode(string, config) { + const buffer = decodeUnsafe(string, config); + if (buffer) return buffer; + throw new Error('Non-base' + config.BASE + ' character'); }