Is there any way to convert a string to base 64 in javascript?

Asked

Viewed 1,791 times

8

Is there any way to convert a string to base 64 in javascript?

In PHP we can do so:

base64_encode('stack overlow'); //c3RhY2sgb3Zlcmxvdw==

How can I do this in javascript?

  • 1

    http://answall.com/questions/92795/como-converter-uma-string-para-base64-em-python

3 answers

11


The modern answer is yes, with the native function btoa(), available in modern browsers.

btoa means basis for Asci, and there is the opposite which is atob.

In that case it would be:

btoa('stack overlow'); // "c3RhY2sgb3Zlcmxvdw=="    

In older browsers this is not so simple and in this case I suggest a more complex function, like this.

Even in modern browsers, there are characters that can break the native function btoa() as an example:

btoa('✓ à la mode'); // Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

In such cases it is necessary to escape/convert these characters. In MDN suggest these functions:

function utf8_to_b64(str) {
    return window.btoa(unescape(encodeURIComponent(str)));
}

function b64_to_utf8(str) {
    return decodeURIComponent(escape(window.atob(str)));
}

More info (in English) here at MDN. In this article there is also a solution for characters that the escape() treats. Once the escape() has been deprecated since forever (since Ecmascript v3 but has actually never been removed) it may be to use an alternative). Here it is:

function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
}

b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="

6

The method btoa() can do the Meeting for you, as well as the atob() does the Decode. The return of

window.btoa('minha string')

is

bWluaGEgc3RyaW5n

and the return of

window.atob('bWluaGEgc3RyaW5n')

it is, as if to expect

my string

EDIT

As pointed out by Omni, both methods have no support for versions prior to IE 10 (always him).

  • 1

    Please note that atob and btoa are not supported by versions prior to IE10.

  • 1

    I found it strange the name of the function. Is there any specific meaning to that name? I think in PHP it became more descriptive

  • 2

    @Wallacemaxters to follow the C convention (as for example atoi). In this case atob means ascii to Base64.

  • This information was very important @Omni

3

As mentioned, atob and btoa do not work in versions prior to IE10.

You can do your own conversion function (withdrawal from here):

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;
  }
}

$encoded = Base64.encode("pt.stackoverflow.com");
alert($encoded)
$decoded = Base64.decode($encoded)
alert($decoded)

  • 2

    What a rush to make a Base64. Long live IE!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.