I have a number, say "123456", and I need to map it to a string, any string. The only constraint on the map functions are:
- each number must map to a unique character string (this means the string can be arbitrarily long)
- character string can only contain 0-9, a-z, A-Z
What map function would produce the shortest strings?
Solutions in JavaScript are preferred.
Note: Clearly the simplest solution is to us开发者_运维技巧e the original number, so make sure you solution does better than that.
You may want to use Base 36 or Base 62.
Base 36 would be the most compact for case-insensitive alphanumerical characters, but if you want to exploit case-sensitivity, Base 62 would be approximately 20% more compact.
For Base 36, you can easily use JavaScript's Number.toString(radix)
method, as follows:
var n = 123456;
n.toString(36); // returns: "2n9c"
For Base 62, you may want to check this forum post. Basically you should be able to do the following:
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"
I made this to create YouTube-like keys. It uses regex to capture numbers and then cycles over a match-list to assemble the the string.
Order of the chars array is arbitrary, you can actually make it anything you like, but once you have it set in place, don't change it later, otherwise you may run into duplicate keys, and make sure you don't have any duplicates.
Here, num, is the variable that holds the input key. It's very long in this sample, but it can be any length.
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);
And here's an implementation in Cold Fusion that uses 1-based arrays rather than javascript's 0-based arrays, in case it helps anyone.
<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>
精彩评论