Use PHP functions in JavaScript

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;
}
external links: original PHP docs | raw js source

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.

Comments

Add Comment
Use:
[CODE]
your_stuff('here');
[/CODE]
for proper code formatting
By submitting code here you are allowing us to use it in php.js hence dual licensing it under the MIT and GPL licenses

Gravatar
John Supplee
13 Dec '11 Permalink

q  I agree with other posters that the utf8_decode in the function is a mistake and a departure from php behaviour. I think the function should be modified to take a second boolean parameter for those who wish to invoke utf8 decoding. The most proper way would be to leave the utf8 decoding out as a separate function. However, there seems to be resistance to that.

function base64_decode (data, isUtf8) {
. . .
	if (isUtf8)
		dec = this.utf8_decode(dec);


Gravatar
Yaffle
13 Oct '11 Permalink

q  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

Gravatar
Josep Sanz
24 Sep '11 Permalink

q  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.

Gravatar
Chris Buckley
1 Sep '11 Permalink

q  The (commented out) native Mozilla functions are the wrong way round: base64_decode === atob and base64_encode === btoa (as in, encoding = binary to ASCII).

Gravatar
Luke Scott
20 Jul '11 Permalink

q  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!!
?>

Gravatar
jamily
11 Dec '10 Permalink

q  Thank you! very good!

Gravatar
zeroneta
5 Jan '10 Permalink

q  

_.unicode = _._.String.fromCharCode

Gravatar
zeroneta
5 Jan '10 Permalink

q  

_.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 );
},

Gravatar
Kevin van Zonneveld
21 Feb '09 Permalink

q  @ Pellentesque malesuada: Thank you, I fixed it in svn, but I can't deploy at the moment. I think everything will be processed Monday!

Gravatar
Pellentesque malesuada
20 Feb '09 Permalink

q  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 = &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=&quot;;
var o1, o2, o3, h1, h2, h3, h4, bits, i = ac = 0, dec = &quot;&quot;, tmp_arr = [];

data += '';

while (i &lt; 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&lt;&lt;18 | h2&lt;&lt;12 | h3&lt;&lt;6 | h4;

o1 = bits&gt;&gt;16 &amp; 0xff;
o2 = bits&gt;&gt;8 &amp; 0xff;
o3 = bits &amp; 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;
}

Gravatar
Kevin van Zonneveld
8 May '08 Permalink

q  @ 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.

Gravatar
Aman Gupta
8 May '08 Permalink

q  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.

Gravatar
Kevin van Zonneveld
25 Apr '08 Permalink

q  @ TXGruppi: I've added a:
[CODE=&quot;Javascript&quot;]
// mozilla has this native
if (typeof window['atob'] == 'function') {
return atob(data);
}
[/CODE]
To make use of mozilla's native base64 functions.

Gravatar
TXGruppi
23 Apr '08 Permalink

q  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

Gravatar
TXGruppi
8 Apr '08 Permalink

q  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=&quot;Javascript&quot;]
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


Contribute a New function

More functions

In this category

» base64_decode
base64_encode
get_headers
get_meta_tags
http_build_query
parse_url
rawurldecode
rawurlencode
urldecode
urlencode

Support us

spread the word:


Use any PHP function in JavaScript


These kind folks have already donated: AYHAN BARI*, Nikita Ekshiyan, Nikita Ekshiyan, Petr Pavel, @HalfWinter, Paulo Freitas, Andros Peña Romo, @andorosu, Raimund Szabo, Nitin Gupta, @nikosdion, Anonymous, Anonymous and Shawn Houser.
<your name here>

Click here to lend your support to: phpjs and make a donation at www.pledgie.com !