basex-encoder
Version:
Encode / decode any base X to and from string or buffer
82 lines • 2.74 kB
JavaScript
export const encoder = (ALPHABET, defaultEncoding = 'utf8') => {
const ALPHABET_MAP = {};
const BASE = ALPHABET.length;
const LEADER = ALPHABET.charAt(0);
for (let z = 0; z < ALPHABET.length; z += 1) {
const x = ALPHABET.charAt(z);
if (ALPHABET_MAP[x] !== undefined) {
throw new TypeError(`'${x}' is duplicate!`);
}
ALPHABET_MAP[x] = z;
}
const encodeFromBuffer = (source) => {
const sourceLen = source.length;
if (sourceLen === 0) {
return '';
}
const digits = [0];
for (let i = 0; i < sourceLen; i += 1) {
let carry = source[i];
const digitsLen = digits.length;
for (let j = 0; j < digitsLen; j += 1) {
carry += digits[j] << 8;
digits[j] = carry % BASE;
carry = (carry / BASE) | 0;
}
while (carry > 0) {
digits.push(carry % BASE);
carry = (carry / BASE) | 0;
}
}
let str = '';
const lastSourceIndex = sourceLen - 1;
for (let k = 0; source[k] === 0 && k < lastSourceIndex; k += 1) {
str += LEADER;
}
for (let q = digits.length - 1; q >= 0; q -= 1) {
str += ALPHABET[digits[q]];
}
return str;
};
const decodeToBuffer = (encoded) => {
if (encoded.length === 0) {
return Buffer.allocUnsafe(0);
}
const bytes = [0];
const strLen = encoded.length;
for (let i = 0; i < strLen; i += 1) {
const value = ALPHABET_MAP[encoded[i]];
if (value === undefined) {
return null;
}
let carry = value;
const bytesLen = bytes.length;
for (let j = 0; j < bytesLen; j += 1) {
carry += bytes[j] * BASE;
bytes[j] = carry & 0xff;
carry >>= 8;
}
while (carry > 0) {
bytes.push(carry & 0xff);
carry >>= 8;
}
}
const lastStrIndex = encoded.length - 1;
for (let k = 0; encoded[k] === LEADER && k < lastStrIndex; k += 1) {
bytes.push(0);
}
return Buffer.from(bytes.reverse());
};
const encode = (str, encoding = defaultEncoding) => encodeFromBuffer(Buffer.from(str, encoding));
const decode = (encoded, encoding = defaultEncoding) => {
const buffer = decodeToBuffer(encoded);
return buffer && buffer.toString(encoding);
};
return {
encode,
decode,
encodeFromBuffer,
decodeToBuffer,
};
};
//# sourceMappingURL=index.js.map