Skip to content

Instantly share code, notes, and snippets.

@bytespider
Forked from 140bytes/LICENSE.txt
Created May 24, 2011 10:08
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save bytespider/988463 to your computer and use it in GitHub Desktop.
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"
]
}
@mathiasbynens
Copy link

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.

@bytespider
Copy link
Author

cheers, did those

@mathiasbynens
Copy link

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.

@bytespider
Copy link
Author

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
Copy link

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
Copy link

jed commented May 24, 2011

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

@bytespider
Copy link
Author

@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
Copy link

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.

@bytespider
Copy link
Author

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
Copy link

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.

@bytespider
Copy link
Author

Oh thats an awesome trick, shaved another 4bytes off

@jed
Copy link

jed commented Jul 11, 2011

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

@haggen
Copy link

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.

@bytespider
Copy link
Author

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