根据散列函数的输出给定整数输入var i = 1234567890
,我需要创建一个缩短的,区分大小写的字母数字字符串。这是为了使用带有区分大小写的散列参数的短URL,例如http://example.com/?hash=1M0nlPk
。
JavaScript的i.toString(36)
将使用字符0-9和a-z。这是解决方案的一部分。但是,我需要对未知或可配置长度的字符集进行操作,例如012abcABC
。如何将int转换为仅包含此字符集的字符串?
更新:我改进了这个问题的措辞。它不是Fastest way to convert a number to radix 64 in JavaScript?的副本,因为字符集是任意的。该问题中的一些答案可能适用于这个问题,但我认为这是一个根本不同的问题。
答案 0 :(得分:3)
这是“Base64”转换问题的变体,可由“base n”库回答。但是,对于这个问题,这些库可能“过度”,因此下面是基于simple & elegant solution by @Reb.Cabin的修改代码。还要感谢编辑@callum,@ Phipip Kaplan,@ Oka这段代码。
在此回复中,删除了常用于创建诅咒词的元音和各种“问题字母”,因此随机整数哈希不会创建令人反感的短网址。
// Based on Base64 code by @Reb.Cabin, edits by @callum, @philip Kaplan, @Oka available at https://stackoverflow.com/a/6573119/3232832
BaseN = {
_Rixits :
// 0 8 16 24 32 40 48 56 63
// v v v v v v v v v
"0123456789BDGHJKLMNPQRTVWXYZbdghjklmnpqrtvwxyz-_",
// original base64
// "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_",
// You have the freedom, here, to choose the glyphs you want for
// representing your base-64 numbers.
// This cannot handle negative numbers and only works on the
// integer part, discarding the fractional part.
fromNumber : function(number) {
if (isNaN(Number(number)) || number === null ||
number === Number.POSITIVE_INFINITY)
throw "The input is not valid";
if (number < 0)
throw "Can't represent negative numbers now";
var rixit; // like 'digit', only in some non-decimal radix
var residual = Math.floor(number);
var result = '';
var rixitLen = this._Rixits.length;
while (true) {
rixit = residual % rixitLen;
result = this._Rixits.charAt(rixit) + result;
residual = Math.floor(residual / rixitLen);
if (residual === 0)
break;
}
return result;
},
toNumber : function(rixits) {
var result = 0;
for (var e = 0; e < rixits.length; e++) {
result = (result * this._Rixits.length) + this._Rixits.indexOf(rixits[e]);
}
return result;
}
};
var i = 1234567890;
var encoded = BaseN.fromNumber(1234567890);
var decoded = BaseN.toNumber(encoded);
document.writeln('Given character set "' + BaseN._Rixits + '", the number ' + i + ' is encoded to ' + encoded + ' then back again to ' + decoded + '.');