UNPKG

@nodecfdi/base-converter

Version:

Librería que convierte un número entre bases arbitrarias

105 lines (103 loc) 3.02 kB
// src/base_converter_sequence.ts var BaseConverterSequence = class _BaseConverterSequence { sequence; #length; constructor(sequence) { _BaseConverterSequence.checkIsValid(sequence); this.sequence = sequence.toUpperCase(); this.#length = new TextEncoder().encode(sequence).byteLength; } static isValid(value) { try { _BaseConverterSequence.checkIsValid(value); return true; } catch { return false; } } static checkIsValid(sequence) { const length = new TextEncoder().encode(sequence).byteLength; if (length < 2) { throw new Error("Sequence does not contains enough elements"); } if (length !== sequence.length) { throw new Error("Cannot use multibyte strings in dictionary"); } const repeated = [...sequence.toUpperCase()].some((value, index, a) => a.lastIndexOf(value) !== index); if (repeated) { throw new Error("The sequence has not unique values"); } } toString = () => this.sequence; value() { return this.sequence; } length() { return this.#length; } }; // src/base_converter.ts var BaseConverter = class _BaseConverter { #sequence; constructor(sequence) { this.#sequence = sequence; } static createBase36() { return new _BaseConverter(new BaseConverterSequence("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")); } sequence() { return this.#sequence; } maximumBase() { return this.#sequence.length(); } convert(input, frombase, tobase) { const frombaseInt = Math.floor(frombase); const tobaseInt = Math.floor(tobase); let inputValue = input.toUpperCase(); if (frombaseInt < 2 || frombaseInt > this.maximumBase()) { throw new Error("Invalid from base"); } if (tobaseInt < 2 || tobaseInt > this.maximumBase()) { throw new Error("Invalid to base"); } const originalSequence = this.sequence().value(); if (inputValue === "") { inputValue = originalSequence[0]; } const chars = originalSequence.slice(0, Math.max(0, frombaseInt)); if (!new RegExp(`^[${chars}]+$`, "u").test(inputValue)) { throw new Error("The number to convert contains invalid characters"); } let { length } = inputValue; const values = []; for (let index = 0; index < length; index += 1) { values.push(originalSequence.indexOf(inputValue.charAt(index))); } let result = ""; let newlen = 0; do { let divide = 0; newlen = 0; for (let index = 0; index < length; index += 1) { divide *= frombaseInt; divide += values[index]; if (divide >= tobaseInt) { values[newlen] = Math.floor(divide / tobaseInt); divide %= tobaseInt; newlen += 1; } else if (newlen > 0) { values[newlen] = 0; newlen += 1; } } length = newlen; result = `${originalSequence[divide]}${result}`; } while (newlen > 0); return result; } }; export { BaseConverter, BaseConverterSequence };