@nodecfdi/base-converter
Version:
Librería que convierte un número entre bases arbitrarias
105 lines (103 loc) • 3.02 kB
JavaScript
// 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
};