开发者问题收集

在 JavaScript 中从任意基数的整数生成字符串

2017-12-19
557

在 JavaScript 中,您可以像这样从数字生成字符串:

(123).toString(36) // => "3f"

如果您尝试使用任意基数:

(123).toString(40)

您将得到

Uncaught RangeError: toString() radix argument must be between 2 and 36
    at Number.toString (<anonymous>)
    at <anonymous>:1:7

想知道如何根据任意字母生成字符串。假设您有这个字母表:

abcdefghijklmnopqrstuvwxyz0123456789+-

那么它将是这样的:

toString(123, 'abcdefghijklmnopqrstuvwxyz0123456789+-')

并且它会打印出一些内容(我不知道是什么),例如 3+ ,从字母表中挑选。

想知道如何在 JavaScript 中做到这一点,不确定“基数”是否与它有关。谢谢。

更新 :正在查看如何逆转它,又名 fromString(string)

3个回答

当您要求任意长度的 parseInt 时,您可以使用给定的字符串并通过将前一个减少值与代码长度相乘并添加代码字符位置的数值来减少它。

另外还提供了 toString 函数。

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

function toString(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; }
Nina Scholz
2017-12-19

您可以模拟执行此操作:

const toString = (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:

const fromStringBuilder = (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+")) // 1138
console.log(toAlphabet(1138)) // "3+"
console.log(toAlphabet(fromAlphabet("3+"))) // "3+"

注意:字母表必须是至少包含两个字符的字符串。否则,循环将无限。

注意 2:您必须按照示例中的相反顺序传递字母表才能获得完全相同的输出。

lilezek
2017-12-19

这适用于 任何 大于 2 的基数。您所要做的就是填充 keys 数组,而 basekeys 数量计算得出。

toString(123, 'abcdefghijklmnopqrstuvwxyz0123456789+-') 的输出将为 dj

fromString('dj', 'abcdefghijklmnopqrstuvwxyz0123456789+-') 的输出将为 123

运行代码底部的代码片段即可查看。

这是代码:

// Converts a string back to it's original number form
function fromString(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);
        else return 'Invalid code.';
    }
    return value;
}

// Converts a number from decimal base to base of keys.length
// also, it assumes you enter correct data
function toString(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 click
function encryptDecrypt()
{
    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>
    <td colspan="2"><label for="getTheKeys">Enter the key string: </label><input type="text" id="getTheKeys" value="abcdefghijklmnopqrstuvwxyz0123456789+-" size="53"/></td>
  <tr>
  <tr>
    <td><label for="encrypt">Encrypt: </label><input type="text" id="encrypt" value="" placeholder="Enter a number"/></td>
    <td class="giveMeSomeSpace"><label for="encrypted">Encrypted: </label><input type="text" id="encrypted" value="" readonly="readonly" /></td>
  <tr>
  <tr>
    <td><label for="decrypt">Decrypt: </label><input type="text" id="decrypt" value="" placeholder="Enter a key combination"/></td>
    <td class="giveMeSomeSpace"><label for="decrypted">Decrypted: </label><input type="text" id="decrypted" value="" readonly="readonly" /></td>
  <tr>
</table>

<input type="button" id="checkNow" value="Go" onclick="encryptDecrypt();" />
Ivan86
2017-12-20