Skip to content Skip to sidebar Skip to footer

Generate String From Integer With Arbitrary Base In Javascript

In JavaScript you can generate a string from a number like this: (123).toString(36) // => '3f' If you try to do arbitrary base: (123).toString(40) You get Uncaught RangeError:

Solution 1:

While you asked for a parseInt for an arbitrary length, you could use the given string and reduce it by multiplying the former reduce value with the code length and adding the numerical value of the position of the code character.

Additional is the toString function supplied.

functionparseInt(value, code) {
    return [...value].reduce((r, a) => r * code.length + code.indexOf(a), 0);
}

functiontoString(value, code) {
    var digit,
        radix= code.length,
        result = '';

    do {
        digit = value % radix;
        result = code[digit] + result;
        value = Math.floor(value / radix);
    } while (value)

    return result;
}

console.log(parseInt('dj', 'abcdefghijklmnopqrstuvwxyz0123456789+-'));
console.log(toString(123, 'abcdefghijklmnopqrstuvwxyz0123456789+-'));
console.log(parseInt('a', 'abcdefghijklmnopqrstuvwxyz0123456789+-'));
console.log(toString(0, 'abcdefghijklmnopqrstuvwxyz0123456789+-'));
.as-console-wrapper { max-height: 100%!important; top: 0; }

Solution 2:

You can simulate that doing:

consttoString = (number, alphabet) => {
  let result = "";
  while (number) {
      const digit = number%alphabet.length;
      number = (number/alphabet.length)|0;
      result = alphabet[digit] + result;
  }
  return result || alphabet[0]; 
}

//////////////////// For the opposite, you can use this:constfromStringBuilder = (alphabet) => {
  const alphabetKeys = {};
  for (let i = 0; i < alphabet.length; i++) {
    alphabetKeys[alphabet[i]] = i;
  }

  return(string) => {
    return [...string].reduce((a,v) => a * alphabet.length + alphabetKeys[v],0);
  }
}

//////////////////// Here you have example usage:

toAlphabet = (number) =>toString(number, 'abcdefghijklmnopqrstuvwxyz0123456789+-')
fromAlphabet = fromStringBuilder('abcdefghijklmnopqrstuvwxyz0123456789+-')

console.log(fromAlphabet("3+")) // 1138console.log(toAlphabet(1138)) // "3+"console.log(toAlphabet(fromAlphabet("3+"))) // "3+"

Note: alphabet must be a string with at least two chars. Otherwise, the loop will be infinite.

Note 2: you have to pass the alphabet in the reverse order from your example to achieve the same exact output.

Solution 3:

This works for any base higher than 2. All you have to do is populate the keys array, while the base is calculated by the number of keys.

The output of toString(123, 'abcdefghijklmnopqrstuvwxyz0123456789+-') would be dj.

The output of fromString('dj', 'abcdefghijklmnopqrstuvwxyz0123456789+-') would be 123.

Run the snippet at the bottom of the code to see.

This is the code:

// Converts a string back to it's original number formfunctionfromString(string, keys)
{
  var base = keys.length;
  var value = 0;
  
  if(base >= 2)
    for(var i=0; i<string.length; i++)
    {
        if(keys.indexOf(string[i]) != -1) value += keys.indexOf(string[i])*Math.pow(base,string.length - i - 1);
        elsereturn'Invalid code.';
    }
    return value;
}

// Converts a number from decimal base to base of keys.length// also, it assumes you enter correct datafunctiontoString(number, keys)
{
  var ready = false;
  var base = keys.length;
  var result = [];
  
  if(base >= 2)
    while(true)
    {
      result.unshift(keys[number % base]);
      number = Math.floor(number/base);
      if(number < 1) break;
    }
    return result.join('');
}

// Function that handles events on button clickfunctionencryptDecrypt()
{
    var keys = document.getElementById('getTheKeys').value.split('');
    var encrypt = document.getElementById('encrypt').value;
    var encrypted = document.getElementById('encrypted');
    var decrypt = document.getElementById('decrypt').value;
    var decrypted = document.getElementById('decrypted');
    
    if(keys != '' && keys.length > 1)
    {
        if(encrypt != '' && parseInt(encrypt)) encrypted.value = toString(parseInt(encrypt), keys);
        if(decrypt != '') decrypted.value = fromString(decrypt, keys);
    }
}
.giveMeSomeSpace
{
  padding-left:47px;
}
<table><tr><tdcolspan="2"><labelfor="getTheKeys">Enter the key string: </label><inputtype="text"id="getTheKeys"value="abcdefghijklmnopqrstuvwxyz0123456789+-"size="53"/></td><tr><tr><td><labelfor="encrypt">Encrypt: </label><inputtype="text"id="encrypt"value=""placeholder="Enter a number"/></td><tdclass="giveMeSomeSpace"><labelfor="encrypted">Encrypted: </label><inputtype="text"id="encrypted"value=""readonly="readonly" /></td><tr><tr><td><labelfor="decrypt">Decrypt: </label><inputtype="text"id="decrypt"value=""placeholder="Enter a key combination"/></td><tdclass="giveMeSomeSpace"><labelfor="decrypted">Decrypted: </label><inputtype="text"id="decrypted"value=""readonly="readonly" /></td><tr></table><inputtype="button"id="checkNow"value="Go"onclick="encryptDecrypt();" />

Solution 4:

Let's make a simple function for base 10 to base N.

functionb102bN (n,b, r = []){
  vargetNumeral = d => d < 10 ? d : String.fromCharCode(d+87);
  
  return n ? (r.unshift(getNumeral(n%b)), b102bN(~~(n/b), b, r)) : r.join("");
}

console.log(b102bN(123,36));
console.log(b102bN(1453,40)); // obviously base 40 requires interesting characters as numerals

Post a Comment for "Generate String From Integer With Arbitrary Base In Javascript"