Base64 Binary Decoding in Javascript

Currently all the base64 decoders in javascript are for strings, not suitable for binary data, the common example is if you uses a canvas element and get their base64 representation ( canvas.toDataURL() ) usually you will upload and in the server do the base64 decode, if you want to process the data in javascript you will find the data will got corrupted since it’s processed as string.

This script is using the new javascript array typed, the basic usage is decoding the base64 into an Uint8Array you can call like:

var uintArray = Base64Binary.decode(base64_string);

The other is wrap the Uint8Array into an ArrayBuffer, this is very helpful for example to upload a file through FormData ( formdata.append("file", arraybuffer, "test.png") ), you can use with:

var byteArray = Base64Binary.decodeArrayBuffer(base64_string);

You can check the code here:
https://github.com/danguer/blog-examples/blob/master/js/base64-binary.js

Share
  • Chris

    this is really awesome, you saved my day :)

  • Anonymous

    Thanks for sharing this code! I’ve been doing some base64 decoding with it and I noticed that the array I was getting from your functions were always 1 element too short.

    I added a +1 to line 56 and it seemed to fix the problem:

    var bytes = Math.ceil( (3*input.length) / 4.0) + 1;

    I don’t fully understand why this is needed, but it seemed to fix the problems I encountered when trying to decode strings of various lengths. Hope this helps someone else…

  • sachin

    plz give me code to decode base64 data to original format.. m tired to surf google whole day but not able to find any kind of code..please provide me code…through the above file we can get uint8array but how to find original format…plaese mail me code at monugoyal89@gmail.com

  • Guest

    The actual bug is in the preceding lines, which read:

    var lkey1 = this._keyStr.indexOf(input.charAt(input.length – 1));
    var lkey2 = this._keyStr.indexOf(input.charAt(input.length – 1));

    The correct code is:

    var lkey1 = this._keyStr.indexOf(input.charAt(input.length – 1));
    var lkey2 = this._keyStr.indexOf(input.charAt(input.length – 2));

  • Fghfgh

    you forgot encoding

  • http://twitter.com/ck1125 Eli Ezeugoh

    Daniel this was a useful post. Thanks for the code.

  • Dan

    Hey Daniel. Great job with the code!

    I’ve been experimenting / trying to convert base64 to png using your code and something is just not working. I was wondering if I could get your opinion.

    Here’s what I have:

    var contents=””;
    var canvas = document.getElementById(‘mycanvas’);
    var imageData = canvas.toDataURL().replace(/data:image/png;base64,/,”);
    var uintArray = Base64Binary.decode(imageData);

    for(var j = 0; j <= uintArray.length-1 ; j++)
    {
    contents+=uintArray[j];
    }
    console.log(contents);

    Then I am copying contents into a text file, saving it as image.png and I try to open it. I did this both programmatically and manually(copy/paste).

    This might be totally wrong. How would you crate a file and write all of this info to it, such that you can open it as an image?

    Thanks,
    D

  • Sdhadhadh

    hmmm , I don’t understand how it works. Does it?

  • Nitin

    Its returning an object. How do I save it into a png?

  • Jon Belanger

    This is a life saver, thank you!!!

    Maybe there is a better way, but you can get base64 from CryptoJS.AES.decrypt() like this:

    var base64 = CryptoJS.AES.decrypt(response,key).toString(CryptoJS.enc.Base64);

    then if you want to save it to a file using the fileSaver shim, you need to create a blob:

    var blob = new Blob([base64]);
    window.saveAs(blob, filename);

    The trouble is that the Blob constructor will not convert from base64 or the native WordArray returned from decrypt.

    I’m thinking there must be an easier way or some object that will take the base64 and natively convert it, but atob justs corrupts the data, as you say.

    This works:

    var base64 = CryptoJS.AES.decrypt(response,key).toString(CryptoJS.enc.Base64);
    var uintArray = Base64Binary.decode(base64);
    var blob = new Blob([uintArray]);
    window.saveAs(blob, file);

    Is this really the only way?

    Also, what should be the upper bounds for the amount of data this object will return?

    THANKS AGAIN

  • Konrad Gądek

    I was struggling with this for just too long… Thank you very much!

  • Naresh Tank

    you made my day..Greate work…Thank you so much.

  • giri

    Thanks Dan u made my day …

  • Mario Ruiz

    Did you know that audi is using it in some of his sites (firefox)

    http://onemillionreasons.audi.de/3d.html#523eaa39ec8d830783000006

    Augure!!!

  • http://www.danguer.com Daniel Guerrero

    I didn’t know; thanks for the information!