Friday, May 10, 2024
 Popular · Latest · Hot · Upcoming
118
rated 0 times [  123] [ 5]  / answers: 1 / hits: 34961  / 13 Years ago, thu, june 2, 2011, 12:00:00

In JavaScript you can convert a number to a string representation with a specific radix as follows:



(12345).toString(36) // 9ix


...and you can convert it back to a regular number like this:



parseInt(9ix, 36) // 12345


36 is the highest radix you can specify. It apparently uses the characters 0-9 and a-z for the digits (36 total).



My question: what's the fastest way to convert a number to a base 64 representation (for example, using A-Z, and - and _ for the extra 28 digits)?






Update: Four people have posted responses saying this question is duplicated, or that I'm looking for Base64. I'm not.



Base64 is a way of encoding binary data in a simple ASCII character set, to make it safe for transfer over networks etc. (so that text-only systems won't garble the binary).



That's not what I'm asking about. I'm asking about converting numbers to a radix 64 string representation. (JavaScript's toString(radix) does this automatically for any radix up to 36; I need a custom function to get radix 64.)






Update 2: Here are some input & output examples...



0   → 0
1 → 1
9 → 9
10 → a
35 → z
61 → Z
62 → -
63 → _
64 → 10
65 → 11
128 → 20
etc.

More From » javascript

 Answers
4

Here is a sketch for a solution for NUMBERS (not arrays of bytes :)



only for positive numbers, ignores fractional parts, and not really tested -- just a sketch!



Base64 = {

_Rixits :
// 0 8 16 24 32 40 48 56 63
// v v v v v v v v v
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/,
// You have the freedom, here, to choose the glyphs you want for
// representing your base-64 numbers. The ASCII encoding guys usually
// choose a set of glyphs beginning with ABCD..., but, looking at
// your update #2, I deduce that you want glyphs beginning with
// 0123..., which is a fine choice and aligns the first ten numbers
// in base 64 with the first ten numbers in decimal.

// This cannot handle negative numbers and only works on the
// integer part, discarding the fractional part.
// Doing better means deciding on whether you're just representing
// the subset of javascript numbers of twos-complement 32-bit integers
// or going with base-64 representations for the bit pattern of the
// underlying IEEE floating-point number, or representing the mantissae
// and exponents separately, or some other possibility. For now, bail
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 = '';
while (true) {
rixit = residual % 64
// console.log(rixit : + rixit);
// console.log(result before : + result);
result = this._Rixits.charAt(rixit) + result;
// console.log(result after : + result);
// console.log(residual before : + residual);
residual = Math.floor(residual / 64);
// console.log(residual after : + residual);

if (residual == 0)
break;
}
return result;
},

toNumber : function(rixits) {
var result = 0;
// console.log(rixits : + rixits);
// console.log(rixits.split('') : + rixits.split(''));
rixits = rixits.split('');
for (var e = 0; e < rixits.length; e++) {
// console.log(_Rixits.indexOf( + rixits[e] + ) : +
// this._Rixits.indexOf(rixits[e]));
// console.log(result before : + result);
result = (result * 64) + this._Rixits.indexOf(rixits[e]);
// console.log(result after : + result);
}
return result;
}
}


UPDATE: Here's some (very lightweight) testing of the above, for running in NodeJs where you have console.log.



function testBase64(x) {
console.log(My number is + x);
var g = Base64.fromNumber(x);
console.log(My base-64 representation is + g);
var h = Base64.toNumber(g);
console.log(Returning from base-64, I get + h);
if (h !== Math.floor(x))
throw TEST FAILED;
}

testBase64(0);
try {
testBase64(-1);
}
catch (err) {
console.log(caught >>>>>> + err);
}
try {
testBase64(undefined);
}
catch (err) {
console.log(caught >>>>>> + err);
}
try {
testBase64(null);
}
catch (err) {
console.log(caught >>>>>> + err);
}
try {
testBase64(Number.NaN);
}
catch (err) {
console.log(caught >>>>>> + err);
}
try {
testBase64(Number.POSITIVE_INFINITY);
}
catch (err) {
console.log(caught >>>>>> + err);
}
try {
testBase64(Number.NEGATIVE_INFINITY);
}
catch (err) {
console.log(caught >>>>>> + err);
}

for(i=0; i<100; i++)
testBase64(Math.random()*1e14);

[#91903] Wednesday, June 1, 2011, 13 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
miles

Total Points: 256
Total Questions: 111
Total Answers: 104

Location: Benin
Member since Fri, Mar 24, 2023
1 Year ago
;