JavaScript base64_decode
Decodes string using MIME base64 algorithm
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 29 3031 32 33 34 3536 37 38 39 4041 42 43 44 4546 47 48 49 5051 52 53 54 5556 57 58 59 60 | function base64_decode (data) { // Decodes string using MIME base64 algorithm // // version: 1109.2015 // discuss at: http://phpjs.org/functions/base64_decode // + original by: Tyler Akins (http://rumkin.com) // + improved by: Thunder.m // + input by: Aman Gupta // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + bugfixed by: Onno Marsman // + bugfixed by: Pellentesque Malesuada // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + input by: Brett Zamir (http://brett-zamir.me) // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // - depends on: utf8_decode // * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA=='); // * returns 1: 'Kevin van Zonneveld' // mozilla has this native // - but breaks in 2.0.0.12! //if (typeof this.window['btoa'] == 'function') { // return btoa(data); //} var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, dec = "", tmp_arr = []; if (!data) { return data; } data += ''; do { // unpack four hexets into three octets using index points in b64 h1 = b64.indexOf(data.charAt(i++)); h2 = b64.indexOf(data.charAt(i++)); h3 = b64.indexOf(data.charAt(i++)); h4 = b64.indexOf(data.charAt(i++)); bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; o1 = bits >> 16 & 0xff; o2 = bits >> 8 & 0xff; o3 = bits & 0xff; if (h3 == 64) { tmp_arr[ac++] = String.fromCharCode(o1); } else if (h4 == 64) { tmp_arr[ac++] = String.fromCharCode(o1, o2); } else { tmp_arr[ac++] = String.fromCharCode(o1, o2, o3); } } while (i < data.length); dec = tmp_arr.join(''); dec = this.utf8_decode(dec); return dec; } |
Examples
Running
1 | base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA=='); |
Should return
1 | 'Kevin van Zonneveld' |
Dependencies
In order to use this function, you also need:
Open syntax issues
php.js uses JsLint to help us keep our code consistent and prevent some common bugs.
Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.
Authors
Thanks to the following developers, you get to have base64_decode goodness in JavaScript.
Good implementation, but doesn't work for base64 strings without padding ("==" or "=")
(From a theoretical point of view the padding character is not needed, since the number of missing bytes can be calculated from the number of Base64 digits, see http://en.wikipedia.org/wiki/Base64#Padding)
and here is my implementation: https://gist.github.com/1284012
https://gist.github.com/1284012
I'm using base64_decode to decode a binary PDF. I detect that the call to utf8_decode used at last of the function is causing problems when work directly with binary data.
What is the reason of use this utf8_decode???
I understand that play with base64_encode and base64_decode, must be as ping-pong and be independent of the contenst (UTF8 is assumed???)
The ping-pong refers to do for example base64_decode(base64_encode(BINARY_PDF_CONTENTS)) must return directly the BINARY_PDF_CONTENTS.
Thanks.
Josep.
The (commented out) native Mozilla functions are the wrong way round: base64_decode === atob and base64_encode === btoa (as in, encoding = binary to ASCII).
I don't know who added the "dec = this.utf8_decode(dec);" bit, but this is NOT correct. This line causes raw binary data to be mangled. Removing this line fixes the problem.
Base64 does not, and should not, care about the charset. If you are expecting utf8 you can use utf8_decode yourself.
PHP does not do this:
<?php
$data = '';
for($i=0; $i < 100000; ++$i)
{
$data .= pack('V', rand(0, 999999999));
}
header('Content-Type: text/plain');
print strlen($data) . "\n"; // ORIGONAL
print strlen( base64_decode(base64_encode($data)) ) . "\n"; // GOOD
print strlen( utf8_decode( base64_decode(base64_encode($data)) ) ) . "\n"; // WRONG!!
?>
_.decode = function( a )
{
return ( a + '' ).replace( /[\x80-\xFF]{2,3}/g, function( a )
{
a = [ a.charCodeAt(0), a.charCodeAt(1), a.charCodeAt(2) ];
return _.unicode( a[2] ? ( a[0] & 15 ) << 12 | ( a[1] & 63 ) << 6 | a[2] & 63 : ( a[0] & 31 ) << 6 | a[1] & 63 );
} );
},
_.base64_decode = function( a )
{
a += '';
for ( var s = 0, d = a.length, f = '', r; s < d; r = [ base64.indexOf( a.charAt( s++ ) ), base64.indexOf( a.charAt( s++ ) ), base64.indexOf( a.charAt( s++ ) ), base64.indexOf( a.charAt( s++ ) ) ], r[4] = r[0] << 18 | r[1] << 12 | r[2] << 6 | r[3], f += r[2] == 64 ? _.unicode( r[4] >> 16 & 0xFF ) : r[3] == 64 ? _.unicode( r[4] >> 16 & 0xFF, r[4] >> 8 & 0xFF ) : _.unicode( r[4] >> 16 & 0xFF, r[4] >> 8 & 0xFF, r[4] & 0xFF ) );
return _.decode( f );
},
@ Pellentesque malesuada: Thank you, I fixed it in svn, but I can't deploy at the moment. I think everything will be processed Monday!
Found an error in base64_decode function. When function receives empty string, it returns 3 characters long string filled with something.
The solution is to replace do/while method with simple while.
function base64_decode( data ) {
// http://kevin.vanzonneveld.net
// + original by: Tyler Akins (http://rumkin.com)
// + improved by: Thunder.m
// + input by: Aman Gupta
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Onno Marsman
// - depends on: utf8_decode
// * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
// * returns 1: 'Kevin van Zonneveld'
// mozilla has this native
// - but breaks in 2.0.0.12!
//if (typeof window['btoa'] == 'function') {
// return btoa(data);
//}
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var o1, o2, o3, h1, h2, h3, h4, bits, i = ac = 0, dec = "", tmp_arr = [];
data += '';
while (i < data.length) { // unpack four hexets into three octets using index points in b64
h1 = b64.indexOf(data.charAt(i++));
h2 = b64.indexOf(data.charAt(i++));
h3 = b64.indexOf(data.charAt(i++));
h4 = b64.indexOf(data.charAt(i++));
bits = h1<<18 | h2<<12 | h3<<6 | h4;
o1 = bits>>16 & 0xff;
o2 = bits>>8 & 0xff;
o3 = bits & 0xff;
if (h3 == 64) {
tmp_arr[ac++] = String.fromCharCode(o1);
} else if (h4 == 64) {
tmp_arr[ac++] = String.fromCharCode(o1, o2);
} else {
tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
}
}
dec = tmp_arr.join('');
dec = utf8_decode(dec);
return dec;
}
@ Aman Gupta: The array join tip has been implemented. As far as the atob goes, thanks for providing additional information. I think for now we should stick with a version that works everywhere until we find out exactly how to safely use the native functions among different mozilla versions.
This implementation is extremely slow in IE due to string concatenation. It is much faster to push onto an array and return array.join('').
In firefox, window.atob works for decoding as long as you don't pass in a large string. Over a certain size, it fails with an 'out of memory' error.
@ TXGruppi: I've added a:
[CODE="Javascript"]
// mozilla has this native
if (typeof window['atob'] == 'function') {
return atob(data);
}
[/CODE]
To make use of mozilla's native base64 functions.
I did a test in IE and not worked the functions atob and btoa, for this reason I did another test to measure the speed of implementation of tasks in Firefox and Internet Explorer. In a loop see that in the FF functions atob and btoa are faster than the functions base64_decode and base64_encode.
The test is available in http://www.txgruppi.com/base64.html
If you can send me your e-mail, I would like to discuss some issues about things I liked in your site.
* Address of my future site.
Any questions send me an email: txgruppi@gmail.com Translated by: Google Translator
Reading the functions I found the base64_encode and base64_decode in a way very complicated.
There are the functions btoa and atob in JavaScript that make this conversion.
[CODE="Javascript"]
var name = 'JavaScript';
var enc = btoa(name);
var dec = atob(enc);
alert(name); // JavaScript
alert(enc); // SmF2YVNjcmlwdA==
alert(dec); // JavaScript
[/CODE]
Any questions send me an email: txgruppi@gmail.com
Translated by: Google Translator


John Supplee
13 Dec '11
function base64_decode (data, isUtf8) { . . . if (isUtf8) dec = this.utf8_decode(dec);