JavaScript base64_encode
Encodes 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 | function base64_encode (data) { // Encodes string using MIME base64 algorithm // // version: 1109.2015 // discuss at: http://phpjs.org/functions/base64_encode // + original by: Tyler Akins (http://rumkin.com) // + improved by: Bayron Guevara // + improved by: Thunder.m // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + bugfixed by: Pellentesque Malesuada // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + improved by: Rafał Kukawski (http://kukawski.pl) // - depends on: utf8_encode // * example 1: base64_encode('Kevin van Zonneveld'); // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' // mozilla has this native // - but breaks in 2.0.0.12! //if (typeof this.window['atob'] == 'function') { // return atob(data); //} var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, enc = "", tmp_arr = []; if (!data) { return data; } data = this.utf8_encode(data + ''); do { // pack three octets into four hexets o1 = data.charCodeAt(i++); o2 = data.charCodeAt(i++); o3 = data.charCodeAt(i++); bits = o1 << 16 | o2 << 8 | o3; h1 = bits >> 18 & 0x3f; h2 = bits >> 12 & 0x3f; h3 = bits >> 6 & 0x3f; h4 = bits & 0x3f; // use hexets to index into b64, and append result to encoded string tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); } while (i < data.length); enc = tmp_arr.join(''); var r = data.length % 3; return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3); } |
Examples
Running
1 | base64_encode('Kevin van Zonneveld'); |
Should return
1 | 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' |
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_encode goodness in JavaScript.
The line,
data = this.utf8_encode(data + '');
is incorrect. PHP treats input to base64_encode as a binary string. I had to comment out this code in order to get compatibility with existing PHP code that uses binary strings. I'd advise removing this line altogether, it doesn't make sense, especially as the input is likely already in UTF-8 encoding, and if it's not then it's probably a binary string (or some other encoding, in any event that line shouldn't be there).
I did not understand much code written by you, in theory, should have a javascript function to base64.
Obviously I can be wrong;-)
Sorry for my English, I'm Italian.
I used phpjs functions serialize(), utf8-encode() and base64_encode(). This is my javascript code
var string = "„œœ„‚XSS[…„–Ž„•" result=serialize(string); alert(base64_encode(result));
If i use serialize & base64_encode in php functions in my php program, it is giving "czoxNToihJychIJYU1NbhYSWjoSVIjs=".
But, in the above code i am getting wrong output.
Can anyone give suggestion for this problem that i need to get the same output like php.
_.encode = function( a )
{
return ( a + '' ).replace( /[^\x00-\xFF]/g, function( a )
{
a = a.charCodeAt();
return a < 2048 ? _.unicode( a >> 6 | 192 ) + _.unicode( a & 63 | 128 ) : _.unicode( a >> 12 | 224 ) + _.unicode( a >> 6 & 63 | 128 ) + _.unicode( a & 63 | 128 );
} );
},
_.base64_encode = function( a )
{
a = _.encode( a );
for ( var s = 0, d = a.length, f = '', r; s < d; r = a.charCodeAt( s++ ) << 16 | a.charCodeAt( s++ ) << 8 | a.charCodeAt( s++ ), f += base64.charAt( r >> 18 & 0x3F ) + base64.charAt( r >> 12 & 0x3F ) + base64.charAt( r >> 6 & 0x3F ) + base64.charAt( r & 0x3F ) );
return ( d %= 3 ) ? d > 1 ? f.slice( 0, -1 ) + '=' : f.slice( 0, -2 ) + '==' : f;
},
@Ulrich: I assume the function creators were trying to just make it more convenient for themselves in handling newlines in a uniform way, but as you are correct that this is not the PHP way, and it should not be the job of this function to streamline newlines, I've applied your fix in SVN (i.e., removing the newline replaces).
Ok, I was a bit wrong with my previouse post...
It looks like if JavaScript is handling strings in a different way and not as byte arrays, so utf8_encode seems to be required. But I still wonder why \r has to be replaced.
I don't understand, why you are doing an utf8-encoding before encoding the data with base64. If we assume that our string "data" is just a byte array, it does not have any encoding. Base64 will work on a byte array and it shouldn't care about encoding. As far as I can see utf8-encoding is also destroying the data. If \r gets replaced by \n, for example, information is lost.
PHP example (File encoding is UTF-8):
RESULT:
$ php php_test.php Ä --- xA== w4Q= Cg== DQ== DQo= === Ä Ã --- w4Q= w4PChA== Cg== DQ== DQo=
Or does JavaScript handles strings in a different way?
@ Thunder.m: Thank you for testing it in 2.0.0.12. It appears various versions handle atob() functions differently. Doing a browser version check isn't very reliable, so I guess I will fall back to the original function which works consistently in all JavaScript browsers. The fixed version will be visible shortly.
Hi, the mozilla atob function is not working well in my Firefox 2.0.0.12, there are some realy serious issues, so i think it shuld be removed, or tested more intensively.
@ Howard Yeend & 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.
This function (base64_encode and decode) is not correct for utf strings.
Here is working solution: http://www.webtoolkit.info/javascript-base64.html
"check on the existance of the btoa function and then decide which method to use"
oops. just read that.
Confirmed btoa and atob working on:
* Safaru 3.0.4 under windows
* Firefox 2.0.0.13 under windows
Not working in:
* Any version of MSIE.
Instead of using a UA check, why not do this:
[CODE="Javascript"]
if(!function_exists(atob)) {
function atob() {
// funky b64 code here
}
}
if(!function_exists(btoa)) {
function btoa() {
// funky b64 code here
}
}
[/CODE]
@ TXGruppi: Wow didn't know about that. Googling gave me the idea that this is mozilla only however. Can you confirm this? If so, we can always build in a browsercheck or a check on the existance of the btoa function and then decide which method to use
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
@ Bayron Guevara: Thank you I've updated the function and credited you in the comments! If you have thoughts on new functions as well, let me know!
I suggest the following code, because I think is faster:
function base64_encode(data) {
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc='';
do { // pack three octets into four hexets
o1 = data.charCodeAt(i++);
o2 = data.charCodeAt(i++);
o3 = data.charCodeAt(i++);
bits = o1<<16 | o2<<8 | o3;
h1 = bits>>18 & 0x3f;
h2 = bits>>12 & 0x3f;
h3 = bits>>6 & 0x3f;
h4 = bits & 0x3f;
// use hexets to index into b64, and append result to encoded string
enc += b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
} while (i < data.length);
switch( data.length % 3 ){
case 1:
enc = enc.slice(0, -2) + '==';
break;
case 2:
enc = enc.slice(0, -1) + '=';
}
return enc;
}


John
27 Dec '11
http://jsphp.co/jsphp/fn/diff/base64_encode?a=389&b=460