Skip to content

Instantly share code, notes, and snippets.

@sebastien-p
Forked from 140bytes/LICENSE.txt
Created August 24, 2011 16:13
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save sebastien-p/1168420 to your computer and use it in GitHub Desktop.
Save sebastien-p/1168420 to your computer and use it in GitHub Desktop.
base62 encode
function (
a, // positive base10 encoded integer
b, // placeholder for result
c // placeholder for modulo
) {
for (
a = a !== +a || a % 1 ? -1 : a, b = ""; // if not a base10 integer, 'a' will be '-1'
// for example, '.5 % 1 == .5' but '1 % 1 == 0'
a >= 0; // also prevents the user to use negative base10 integers
a = Math.floor(a / 62) || -1 // using a bitwise hack here will fail with great numbers
)
// a%62 -> 0-61
// 0-9 | 36-61 | 10-35
// 48-57 | 65-90 | 97-121
// 0-9 | A-Z | a-z
b = String.fromCharCode(((c = a % 62) > 9 ? c > 35 ? 29 : 87 : 48) + c) + b;
return b // will return either an empty or a base62-encoded string
}
function(a,b,c){for(a=a!==+a||a%1?-1:a,b="";a>=0;a=Math.floor(a/62)||-1)b=String.fromCharCode(((c=a%62)>9?c>35?29:87:48)+c)+b;return b}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Sebastien P. https://twitter.com/#!/_sebastienp
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "base62 encode",
"description": "A JavaScript implementation of base62 encode.",
"keywords": [
"base62",
"encode",
"integer",
"number",
"string"
]
}
<!DOCTYPE html>
<title>Foo</title>
<div>Expected value: <b>140bytes</b></div>
<div>Actual value: <b id="ret"></b></div>
<script>
var base62encode = function(a,b,c){for(a=a!==+a||a%1?-1:a,b="";a>=0;a=Math.floor(a/62)||-1)b=String.fromCharCode(((c=a%62)>9?c>35?29:87:48)+c)+b;return b};
document.getElementById("ret").innerHTML = base62encode(3748986303764)
</script>
@jed
Copy link

jed commented Aug 24, 2011

wow, this is great! i wonder if there's enough space to include a decoder...

@jed
Copy link

jed commented Aug 24, 2011

also, i think it might be more appropriate to have return value other than "0".

Number.prototype.toString will throw Number.prototype.toString is not generic in chrome for invalid contexts, for example. this is overkill, clearly, but how about how about at least returning something falsy, like null or an empty string?

@jed
Copy link

jed commented Aug 25, 2011

--length:

function(a,b,c){for(b="";~~a>0;a/=62)b=String.fromCharCode(((c=a%62)>9?c>35?29:87:48)+c)+b;return b||"0"}

@jed
Copy link

jed commented Aug 25, 2011

95 bytes, returning "" instead of "0":

function c(a,b){b=b||"";return~~a?c(a/62,String.fromCharCode(((a%=62)>9?a>35?29:87:48)+a)+b):b}

@sebastien-p
Copy link
Author

@jed : thanks ! The problem is that without ||"0" base62encode(0) will return "". Also, ~~a>0 prevents the user to call the base62 encoding function with a negative number as parameter which would be meaningless.

@sebastien-p
Copy link
Author

I noticed that (for example) base62encode(6631951758436141) fails because of ~~a, it seems better to use Math.floor(a) instead. Wonder if someone can come up with another solution ?

@sebastien-p
Copy link
Author

Working on a much more solid version...

function(a,b,c){for(a=a===+a&&/^\d+$/.test(a)&&a,b="";Math.floor(a);a/=62)b=String.fromCharCode(((c=a%62)>9?c>35?29:87:48)+c)+b;return b||"0"}

And also on decode : https://gist.github.com/1170594

@jed
Copy link

jed commented Aug 25, 2011

very nice work, @sebastien-p.

@sebastien-p
Copy link
Author

@jed : thank you :)

@sebastien-p
Copy link
Author

New version is here ! Still 4 bytes to go, help appreciated :)

@atk
Copy link

atk commented Aug 31, 2011

Simple: instead of a-=a!==+a|/-|\./.test(a)&&{} use a=a>=0&&a|0===a?a:NaN, which is 7 bytes shorter, but essentially does the same.

@sebastien-p
Copy link
Author

@atk : a=a>=0&&a|0===a?a:NaN is great but if 'a' is 'true' it won't be 'NaN'. So I think a=a>=0&&~~a===a?a:-1 is what I need here. Thank you :)

EDIT : ~~a===a also fails with great numbers, for example ~~3748986303764 returns -520145644.

@atk
Copy link

atk commented Aug 31, 2011

We only got JS integers in any case, so the other part would fail if it wasn't serialized.

@sebastien-p
Copy link
Author

Yeehaa, finally a = a !== +a || a % 1 ? -1 : a and a >= 0 did the trick !

135 bytes including input value validation and support for great numbers :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment