|
const Alphabet = { |
|
BINARY: '01', |
|
OCTAL: '01234567', |
|
DECIMAL: '0123456789', |
|
HEXA_DECIMAL: '0123456789abcdef', |
|
ALPHA_LOWER: 'abcdefghijklmnopqrstuvwxyz', |
|
ALPHA_UPPER: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', |
|
ALPHA: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |
|
ALPHA_NUMERIC: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' |
|
}; |
|
|
|
function baseConverter(input, source, target) { |
|
if (source === target) { return input; } |
|
//console.log(input); |
|
//console.log(source, target); |
|
let remainders = []; |
|
let div = 0; |
|
if ((source.length === 2 && target.length !== 10) || (source.length === 2 && !Number.isSafeInteger(parseInt(input)))) { |
|
/* |
|
* convert bin to dec first |
|
* if bin should be converted to not dec |
|
* or if bin is not a safe integer |
|
*/ |
|
let binToDec = 0; |
|
let power = 0; |
|
for (let i = input.length - 1; i >= 0; i--) { |
|
binToDec += parseInt(input[i]) * Math.pow(2, power); |
|
power++; |
|
} |
|
input = binToDec; |
|
if (!Number.isSafeInteger(parseInt(input)) && target.length === 10) { |
|
/* |
|
* if input is not a safe integer |
|
* and should actually be converted from bin to dec |
|
*/ |
|
return input; |
|
} |
|
} else if (source.length !== 2 && source.length !== 10) { |
|
/* |
|
* use dictionary to convert from arbitrary base |
|
* to base10 before moving further |
|
*/ |
|
//console.log('convert:', input, 'from:', source, 'to decimal'); |
|
const sourceBase = source.length; |
|
let sourceToBase10 = 0; |
|
//console.log('sourceBase:', sourceBase); |
|
let power = 0; |
|
for (let i = input.length - 1; i >= 0; i--) { |
|
sourceToBase10 += source.indexOf(input[i]) * Math.pow(sourceBase, power); |
|
power++; |
|
} |
|
input = sourceToBase10; |
|
//input = input.split('').map(item => source.indexOf(item)).join(''); |
|
} |
|
//console.log('input:', input); |
|
input = parseInt(input); |
|
while (input > target.length) { |
|
/* |
|
* convert using remainder approach |
|
*/ |
|
const remainder = input % target.length; |
|
remainders.unshift(remainder); |
|
input = Math.trunc(input / target.length); |
|
//console.log('input:', input, '| remainder:', remainder); |
|
} |
|
//console.log('remainders:', remainders, '| input:', input); |
|
if (source.length === 10 && target.length === 2) { |
|
/* |
|
* fixt for dec to bin convertion |
|
* convert rest if input is still >= 2 |
|
*/ |
|
while (input >= target.length) { |
|
/* |
|
* convert using remainder approach |
|
*/ |
|
const remainder = input % target.length; |
|
remainders.unshift(remainder); |
|
input = Math.trunc(input / target.length); |
|
//console.log('input:', input, '| remainder:', remainder); |
|
} |
|
} |
|
remainders.unshift(input); |
|
//console.log('remainders:', remainders); |
|
remainders = remainders.map(item => target[item]); |
|
return remainders.join(''); |
|
} |
|
|
|
// convert between numeral systems |
|
baseConverter('15', Alphabet.DECIMAL, Alphabet.BINARY); // '1111' |
|
baseConverter('15', Alphabet.DECIMAL, Alphabet.OCTAL); // '17' |
|
baseConverter('1010', Alphabet.BINARY, Alphabet.DECIMAL); // '10' |
|
baseConverter('1010', Alphabet.BINARY, Alphabet.HEXA_DECIMAL); // 'a' |
|
|
|
// other bases |
|
baseConverter('0', Alphabet.DECIMAL, Alphabet.ALPHA); // 'a' |
|
baseConverter('27', Alphabet.DECIMAL, Alphabet.ALPHA_LOWER); // 'bb' |
|
baseConverter('hello', Alphabet.ALPHA_LOWER, Alphabet.HEXA_DECIMAL); // '320048' |
|
baseConverter('SAME', Alphabet.ALPHA_UPPER, Alphabet.ALPHA_UPPER); // 'SAME' |
|
|
|
// advanced |
|
baseConverter('1001001100101100000001011010010', Alphabet.BINARY, Alphabet.DECIMAL); // '1234567890' |
|
baseConverter('1001001100101100000001011010010', Alphabet.BINARY, Alphabet.OCTAL); // '11145401322' |
|
baseConverter('1001001100101100000001011010010', Alphabet.BINARY, Alphabet.HEXA_DECIMAL); // '499602d2' |
|
baseConverter('1001001100101100000001011010010', Alphabet.BINARY, Alphabet.ALPHA_LOWER); // 'dzxprwk' |
|
baseConverter('1001001100101100000001011010010', Alphabet.BINARY, Alphabet.ALPHA); // 'dmSkYk' |
|
baseConverter('1001001100101100000001011010010', Alphabet.BINARY, Alphabet.ALPHA_NUMERIC); // '1ly7vk' |
|
|
|
baseConverter('1337', Alphabet.DECIMAL, Alphabet.BINARY); // '10100111001' |
|
baseConverter('1337', Alphabet.DECIMAL, Alphabet.OCTAL); // '2471' |
|
baseConverter('1337', Alphabet.DECIMAL, Alphabet.HEXA_DECIMAL); // '539' |
|
baseConverter('1337', Alphabet.DECIMAL, Alphabet.ALPHA_LOWER); // 'bzl' |
|
baseConverter('1337', Alphabet.DECIMAL, Alphabet.ALPHA); // 'zL' |
|
baseConverter('1337', Alphabet.DECIMAL, Alphabet.ALPHA_NUMERIC); // 'lz' |
|
|
|
baseConverter('CodeWars', Alphabet.ALPHA, Alphabet.BINARY); // '110100110111011111011110001100111111110000110' |
|
baseConverter('CodeWars', Alphabet.ALPHA, Alphabet.OCTAL); // '646737361477606' |
|
baseConverter('CodeWars', Alphabet.ALPHA, Alphabet.DECIMAL); // '29063972814726' |
|
baseConverter('CodeWars', Alphabet.ALPHA, Alphabet.HEXA_DECIMAL); // '1a6efbc67f86' |
|
baseConverter('CodeWars', Alphabet.ALPHA, Alphabet.ALPHA_LOWER); // 'fjepvaubis' |
|
baseConverter('CodeWars', Alphabet.ALPHA, Alphabet.ALPHA_NUMERIC); // '8fGCU1me' |
|
|
|
// ROT13 with custom alphabet |
|
const customAlpha = 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM'; |
|
baseConverter('PbqrJnef', Alphabet.ALPHA, customAlpha); // 'CodeWars' |
|
baseConverter('chAllEnge', Alphabet.ALPHA, customAlpha); // 'puNyyRatr' |