Преобразуйте число в кратчайшую строку символов, сохраняя уникальность

У меня есть номер, скажем, "123456", и мне нужно сопоставить его со строкой, любой строкой. Единственное ограничение на функции отображения:

  • каждый номер должен сопоставляться с уникальной символьной строкой (это означает, что строка может быть сколь угодно длинной)
  • символьная строка может содержать только 0-9, a-z, A-Z

Какая функция карты создаст кратчайшие строки?

Решения в JavaScript предпочтительны.

Примечание. Очевидно, что самым простым решением является использование исходного номера, поэтому убедитесь, что решение лучше.

Ответы

Ответ 1

Возможно, вы захотите использовать База 36 или База 62.

База 36 была бы наиболее компактной для буквенно-цифровых символов, не учитывающих регистр, но если вы хотите использовать чувствительность к регистру, Base 62 будет примерно на 20% более компактным.

Для Base 36 вы можете легко использовать метод JavaScript Number.toString(radix), как показано ниже:

var n = 123456;
n.toString(36); // returns: "2n9c"

Для Base 62 вы можете проверить этот пост форума. В основном вы должны быть в состоянии сделать следующее:

Number.prototype.toBase = function (base) {
    var symbols = 
    "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
    var decimal = this;
    var conversion = "";

    if (base > symbols.length || base <= 1) {
        return false;
    }

    while (decimal >= 1) {
        conversion = symbols[(decimal - (base * Math.floor(decimal / base)))] + 
                     conversion;
        decimal = Math.floor(decimal / base);
    }

    return (base < 11) ? parseInt(conversion) : conversion;
}

var n = 123456;
n.toBase(62); // returns: "w7e"

Ответ 2

Я сделал это, чтобы создать YouTube-подобные ключи. Он использует регулярное выражение для записи чисел, а затем циклически перебирает список совпадений для сборки строки.

Порядок массива символов произволен, вы можете сделать все, что захотите, но как только вы его установите на место, не изменяйте его позже, иначе вы можете запустить дубликаты ключей и убедиться, t есть дубликаты.

Здесь num - это переменная, которая содержит ключ ввода. Он очень длинный в этом примере, но может быть любой длины.

var chars = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
num = "000102030405060708091011121314151617181920212223242526272829303132333435373839404142434445464748495051525354555657585960616263646566";
getnums = num.match(/(0|6[0-1]|[0-5]?[0-9])/g);
to62 = "";
for (var i=0;i<getnums.length;i++) {
    to62 = to62 + chars[parseInt(getnums[i])];
    // console.log(getnums[i] + ": " + chars[parseInt(getnums[i])])
}
console.log(to62);

И вот реализация в Cold Fusion, которая использует массивы на основе 1, а не массивы на основе javascript 0, если это кому-то помогает.

<cfscript>
  chars = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
  num = "0001020304050607080910111213141516171819202122232425262728293031323334353738394041424344454614748495051525354555657585960616263646566";
  getnums = ReMatch("(0|6[0-1]|[0-5]?[0-9])",num);
  to62 = "";
  for (i=1; i<=arraylen(getnums); i=i+1) {
      to62 = to62 & chars[getnums[i]+1];
  }
  writeoutput(to62);
</cfscript>