简体   繁体   中英

How to change an integer into a string with specified character set in JavaScript

Given an integer input var i = 1234567890 based on the output of a hash function, I need to create a shortened, case sensitive alphanumeric string. This is for purposes of having a short URL with a case-sensitive hashed parameter such as http://example.com/?hash=1M0nlPk .

JavaScript's i.toString(36) would use characters 0-9 and az. That's part of the way to a solution. However, I need to operate on a character set of unknown or configureable length, eg 012abcABC . How could I convert an int to a string consisting only of this character set?

UPDATE: I have improved the wording of this question. It is not a duplicate of Fastest way to convert a number to radix 64 in JavaScript? because the character set is arbitrary. Some of the answers in that question may be adaptable to this question, but I believe it to be a fundamentally different question.

This is a variant of a "Base64" conversion question that can be answered by "base n" libraries. However, these libraries may be "overkill" for this question, so below is modified code based on a simple & elegant solution by @Reb.Cabin . Credit also to editors @callum, @Philip Kaplan, @Oka on this code.

In this response, vowels and various "problem letters" commonly used to create curse words are removed, so a random integer hash will not create an offensive short URL.

 // 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 // vvvvvvvvv "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 + '.'); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM