Javascript Btoa

Not applicable

Hi,

I am trying to use btoa JavaScript function for encodindg base64 and

getting an Error "ReferenceError: "btoa".

Is there any workaround to use "Btoa" or any other encoder i can use for Base64 encoding.

I am failing to Encode special Characters in apigee.

Would really appriciate any help.

Thanks

Solved Solved
3 8 4,143
1 ACCEPTED SOLUTION

@gautam1 ,

Try below code, it should work. I have tested same & it works for me in Apigee Edge Proxy,

var Base64 = {




    _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",




    encode: function(input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;


        input = Base64._utf8_encode(input);


        while (i < input.length) {


            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);


            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;


            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }


            output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);


        }


        return output;
    },




    decode: function(input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;


        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");


        while (i < input.length) {


            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));


            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;


            output = output + String.fromCharCode(chr1);


            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }


        }


        output = Base64._utf8_decode(output);


        return output;


    },


    _utf8_encode: function(string) {
        string = string.replace(/\r\n/g, "\n");
        var utftext = "";


        for (var n = 0; n < string.length; n++) {


            var c = string.charCodeAt(n);


            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if ((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }


        }


        return utftext;
    },


    _utf8_decode: function(utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;


        while (i < utftext.length) {


            c = utftext.charCodeAt(i);


            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if ((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i + 1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i + 1);
                c3 = utftext.charCodeAt(i + 2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }


        }


        return string;
    }


}
    
var origString  = "HelloWorld";    
var encodedString = Base64.encode(origString);
var decodedString = Base64.decode(encodedString);


print(origString);    
print(encodedString);
print(decodedString);

If you are interested, Here is the python based solution too... Keep us posted.

View solution in original post

8 REPLIES 8

@gautam1 ,

Try below code, it should work. I have tested same & it works for me in Apigee Edge Proxy,

var Base64 = {




    _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",




    encode: function(input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;


        input = Base64._utf8_encode(input);


        while (i < input.length) {


            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);


            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;


            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }


            output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);


        }


        return output;
    },




    decode: function(input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;


        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");


        while (i < input.length) {


            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));


            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;


            output = output + String.fromCharCode(chr1);


            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }


        }


        output = Base64._utf8_decode(output);


        return output;


    },


    _utf8_encode: function(string) {
        string = string.replace(/\r\n/g, "\n");
        var utftext = "";


        for (var n = 0; n < string.length; n++) {


            var c = string.charCodeAt(n);


            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if ((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }


        }


        return utftext;
    },


    _utf8_decode: function(utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;


        while (i < utftext.length) {


            c = utftext.charCodeAt(i);


            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if ((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i + 1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i + 1);
                c3 = utftext.charCodeAt(i + 2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }


        }


        return string;
    }


}
    
var origString  = "HelloWorld";    
var encodedString = Base64.encode(origString);
var decodedString = Base64.decode(encodedString);


print(origString);    
print(encodedString);
print(decodedString);

If you are interested, Here is the python based solution too... Keep us posted.

@gautam1 , Just following up, Is above query resolved ?

@Anil Sagar , Apologies for not responding back

Yes that worked ,but i rather choose to Import Base64 Encoder JS refernce file in my proxy and used base64() method for encoding.

I need some help here as well , if you can that would be really appricicable ,

https://community.apigee.com/content/idea/25975/dev-portal-smartdocsswagger-public-access.html

Glad to know @gautam1 , Can you please post your query as a question instead of an idea. I don't want to confuse google bots 😉

@gautam1

Also, Moving forward, If query is resolved, please click on "Accept" link below the answer so that it will be helpful for others too. Thank you.

robinm
Participant IV

Out of interest, simple Base64 encoding is also available calling the undocumented method of the built-in crypto module in Edge. (at the time of writing, there is no decode, however)

Herewith example usage emulating the BasicAuthentication generation policy:

var authString = clientID+":"+clientSecret;

//== Apigee made crypto.js available without needing an include
var AG_outputHash = crypto.base64(crypto.asBytes(authString));

context.setVariable("request.header.Authorization","Basic "+AG_outputHash);

Can any one from APIGEE please confirm if it's safe to use this crypto base64 function for encoding?

Thanks.

crypto.base64(crypto.asBytes(authString));

The crypto module itself is likely to remain and be "safe" to use as per this announcement link from 2016 :-

https://community.apigee.com/articles/30959/apigee-weekly-netflix-crypto-in-edge-nationwide.html

and the docs on the crypto object
https://docs.apigee.com/api-platform/reference/javascript-object-model#crypto

I cannot comment on whether Apigee may ever deprecate this function.
If you are concerned they may do sometime in the future, rather load up your own crypto function as Anil suggested.