Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Base64 Encode
function base64Encode(
a, // string to encode
b, // character table ie, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
c, // placeholder
d, // placeholder
e, // placeholder
f, // placeholder
g, // placeholder
h // placeholder
){
h="";
for(d=0; // initialise the output buffer
a[d]; // check if a value is returned
h+=b[e>>2]+b[e<<4&63|f>>4]+b[f<<2&63|g>>6||64]+b[g&63||64]) // split into 6bits characters and find it in our character table
for(c=4;c<7;)
arguments[c++]=a.charCodeAt(d++) // copy the character code into a variable declared as a placeholder
return h
}
function(a,b,c,d,e,f,g,h){h="";for(d=0;a[d];h+=b[e>>2]+b[e<<4&63|f>>4]+b[f<<2&63|g>>6||64]+b[g&63||64])for(c=4;c<7;)arguments[c++]=a.charCodeAt(d++);return h}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Rob Griffiths http://bytespider.eu
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": "Base64 Encode",
"keywords": [
"140bytes",
"base64",
"encode"
]
}

Nice! A few suggestions:

  • for(d=0;d<a.length;) can be shortened to for(d=0;a[d];).
  • a.charCodeAt can be cached and re-used to save some more bytes.
Owner

bytespider commented May 24, 2011

cheers, did those

Currently you’re caching "charCodeAt" and re-using that, which is great – but since you’re always using it on the same string (a) anyways, you might as well cache a.charCodeAt and re-use that instead. Saves you 9 bytes.

Owner

bytespider commented May 24, 2011

That appears to break the encoding. I tried it and for my test "hello" i should get "aGVsbG8=" however i get "W29iamVj"

I can only assume, the caching of a.charCodeAt looses scope.

jed commented May 24, 2011

seems like you'd be better off putting e, f, and g into an array and working from there; you wouldn't need to cache, would need two fewer vars, wouldn't need to repeat identical operations, etc.

this is really epic.

jed commented May 24, 2011

also, i think you can save a comma by putting the h+= section in the loop post-condition.

Owner

bytespider commented May 24, 2011

@jed, when I had this as an array previously the function was 8bytes bigger. as now the reference to each letter is 3bytes instead of 1.

Unless I've misunderstood. However you putting the h+= into the post conditional is an excellent idea!

Cheers for all the support

jed commented May 24, 2011

i think it would only work if you can somehow introduce another for loop and assign the current index to a reference.

Owner

bytespider commented May 24, 2011

168bytes is the shortest I seem to be able to make this so far.
If it wasn't for that fact << has higher precedence than & I'd loose bytes for all the brackets I have to use

jed commented May 24, 2011

have you considered exploiting the fact that setting an arguments index sets its binding too? that way you could loop but still set local variables.

Owner

bytespider commented May 24, 2011

Oh thats an awesome trick, shaved another 4bytes off

jed commented Jul 11, 2011

hey @bytespider, would you mind taking the comments out of this package.json too?

haggen commented Apr 3, 2012

I really don't know much about encoding strings and stuff, so you tell me if I'm doing something wrong, but...

Comparing to Base64 module for Ruby - http://ruby-doc.org/stdlib-1.9.3/libdoc/base64/rdoc/Base64.html - it gives something very different.

Here's my test:

function base64_encode(a, b, c, d, e, f, g, h) {
  b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  h = '';

  for(d = 0; a[d]; h += b[e >> 2] + b[e << 4 & 63 | f >> 4] + b[f << 2 & 63 | g >> 6 || 64 ] + b[g & 63 || 64]) {
    for(c = 4; c < 7;) {
      arguments[c++] = a.charCodeAt(d++);
    }    
  }

  return h;
}

console.log(base64_encode('123')); //=> AA==

And in Ruby 1.9.3:

require 'base64'; puts Base64.encode64('123') #=> MTIz\n

Note that I prepended the suggest character map into the function.

Owner

bytespider commented Apr 4, 2012

Correct it should be MTIz My implementation breaks because somewhere an undefined isnt being cast to 0. Ie this works
base64Encode("123", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", "", "", "", "", "", "");

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