Base64 encoding and decoding in client-side Javascript

前端 未结 14 2060
挽巷
挽巷 2020-11-22 04:27

Are there any methods in JavaScript that could be used to encode and decode a string using base64 encoding?

相关标签:
14条回答
  • 2020-11-22 05:01

    In Node.js we can do it in simple way

    var base64 = 'SGVsbG8gV29ybGQ='
    var base64_decode = new Buffer(base64, 'base64').toString('ascii');
    
    console.log(base64_decode); // "Hello World"
    
    0 讨论(0)
  • 2020-11-22 05:03

    Modern browsers have built-in javascript functions for Base64 encoding btoa() and decoding atob(). More info about support in older browser versions: https://caniuse.com/?search=atob

    However, be aware that atob and btoa functions work only for ASCII charset. If you need Base64 functions for UTF-8 charset, you can do it with:

    function base64_encode(s) {      
        return btoa(unescape(encodeURIComponent(s)));
    }
    function base64_decode(s) {      
        return decodeURIComponent(escape(atob(s)));
    }
    
    0 讨论(0)
  • 2020-11-22 05:05

    Did someone say code golf? =)

    The following is my attempt at improving my handicap while catching up with the times. Supplied for your convenience.

    function decode_base64(s) {
      var b=l=0, r='',
      m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
      s.split('').forEach(function (v) {
        b=(b<<6)+m.indexOf(v); l+=6;
        if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
      });
      return r;
    }
    

    What I was actually after was an asynchronous implementation and to my surprise it turns out forEach as opposed to JQuery's $([]).each method implementation is very much synchronous.

    If you also had such crazy notions in mind a 0 delay window.setTimeout will run the base64 decode asynchronously and execute the callback function with the result when done.

    function decode_base64_async(s, cb) {
      setTimeout(function () { cb(decode_base64(s)); }, 0);
    }
    

    @Toothbrush suggested "index a string like an array", and get rid of the split. This routine seems really odd and not sure how compatible it will be, but it does hit another birdie so lets have it.

    function decode_base64(s) {
      var b=l=0, r='',
      m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
      [].forEach.call(s, function (v) {
        b=(b<<6)+m.indexOf(v); l+=6;
        if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
      });
      return r;
    }
    

    While trying to find more information on JavaScript string as array I stumbled on this pro tip using a /./g regex to step through a string. This reduces the code size even more by replacing the string in place and eliminating the need of keeping a return variable.

    function decode_base64(s) {
      var b=l=0,
      m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
      return s.replace(/./g, function (v) {
        b=(b<<6)+m.indexOf(v); l+=6;
        return l<8?'':String.fromCharCode((b>>>(l-=8))&0xff);
      });
    }
    

    If however you were looking for something a little more traditional perhaps the following is more to your taste.

    function decode_base64(s) {
      var b=l=0, r='', s=s.split(''), i,
      m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
      for (i in s) {
        b=(b<<6)+m.indexOf(s[i]); l+=6;
        if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
      }
      return r;
    }
    

    I didn't have the trailing null issue so this was removed to remain under par but it should easily be resolved with a trim() or a trimRight() if you'd prefer, should this pose a problem for you.

    ie.

    return r.trimRight();
    

    Note:

    The result is an ascii byte string, if you need unicode the easiest is to escape the byte string which can then be decoded with decodeURIComponent to produce the unicode string.

    function decode_base64_usc(s) {      
      return decodeURIComponent(escape(decode_base64(s)));
    }
    

    Since escape is being deprecated we could change our function to support unicode directly without the need for escape or String.fromCharCode we can produce a % escaped string ready for URI decoding.

    function decode_base64(s) {
      var b=l=0,
      m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
      return decodeURIComponent(s.replace(/./g, function (v) {
        b=(b<<6)+m.indexOf(v); l+=6;
        return l<8?'':'%'+(0x100+((b>>>(l-=8))&0xff)).toString(16).slice(-2);
      }));
    }
    

    nJoy!

    0 讨论(0)
  • 2020-11-22 05:06

    Here is a tightened up version of Sniper's post. It presumes well formed base64 string with no carriage returns. This version eliminates a couple of loops, adds the &0xff fix from Yaroslav, eliminates trailing nulls, plus a bit of code golf.

    decodeBase64 = function(s) {
        var e={},i,b=0,c,x,l=0,a,r='',w=String.fromCharCode,L=s.length;
        var A="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        for(i=0;i<64;i++){e[A.charAt(i)]=i;}
        for(x=0;x<L;x++){
            c=e[s.charAt(x)];b=(b<<6)+c;l+=6;
            while(l>=8){((a=(b>>>(l-=8))&0xff)||(x<(L-2)))&&(r+=w(a));}
        }
        return r;
    };
    
    0 讨论(0)
  • 2020-11-22 05:08

    The php.js project has JavaScript implementations of many of PHP's functions. base64_encode and base64_decode are included.

    0 讨论(0)
  • 2020-11-22 05:09

    Some browsers such as Firefox, Chrome, Safari, Opera and IE10+ can handle Base64 natively. Take a look at this Stackoverflow question. It's using btoa() and atob() functions.

    For server-side JavaScript (Node), you can use Buffers to decode.

    If you are going for a cross-browser solution, there are existing libraries like CryptoJS or code like:

    http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html

    With the latter, you need to thoroughly test the function for cross browser compatibility. And error has already been reported.

    0 讨论(0)
提交回复
热议问题