1

I have a base64 string that represents binary data (e.g. not a nice readable string after you decode it or UTF-8 data otherwise this answer would help me -- Using Javascript's atob to decode base64 doesn't properly decode utf-8 strings). My JS Is

var byteCharacters = atob(base64str);

which results in

InvalidCharacterError: Failed to execute 'atob' on 'WorkerGlobalScope': The string to be decoded contains characters outside of the Latin1 range.

How do I decode a base 64 string that is not ASCII (or even UTF-8 data)?

Edit: Here's an example of the type of string I'm talking about. Using Mac, I can base64 encode a file like so

openssl base64 -in ~/Downloads/star.jpg -out ~/Downloads/star.base64

Here's the resulting base64 string. If you can decode this with JS tools, you've solved the problem. Got the below by doing "cat myfile.base64" so hopefully "cat" or my cutting and pasting didn't introduce any weird characters here.

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
AABJRU5ErkJggg==
Dave
  • 15,639
  • 133
  • 442
  • 830
  • Is the string sharable, or are you able to provide a minimal working example? – Matt Way May 25 '18 at 21:51
  • You're probably not decoding with the same character set that the binary data was encoded with. They must match. Do you know which character set was used for encoding? – Victor Stoddard May 25 '18 at 21:55
  • @VictorStoddard, The original data that was encoded wasn't a readable string. It was like PDF data or image data or something like that. Does the decoding depend on the original file type? Is there just a generic binary decode? – Dave May 25 '18 at 22:01
  • If the result should be binary data why do you call it a string? What is an appropriate data type for the result? – Tom Blodget May 27 '18 at 14:33
  • @TomBlodget, I want my quesiton to be clear. The item "base64str" is indeed a string, since base 64 encoded entitties are all strings, from what I have been told. What it represents is not. Where in my question do I refer to the entity that was encoded as a string? I want to make this quesiton clear before it goes to its inevitable bounty. – Dave May 27 '18 at 16:38
  • So, the task is to convert from data as base64 in a `String` to bytes in, say, a `Uint8Array`? – Tom Blodget May 27 '18 at 16:42
  • Sure Uint8Array would be just fine. Or an ArrayBuffer. As long as teh binary data is returned to its original form. – Dave May 28 '18 at 13:30
  • The real problem lies in generation of base64 string. How are you getting the base64 string? The string may be getting corrupted. I tried with uint8Array and an image Here is the code for Uint8Array ar = [1,2,3]; uar = Uint8Array.from(ar) base64str = btoa(uar) byteCharacters = atob(base64str) // "1,2,3" //No errors were encountered. – Sreeragh A R May 29 '18 at 16:14
  • @SreeraghAR, added an example into my question. The file was base64 encoded using the command "openssl base64 -in ~/Downloads/star.jpg -out ~/Downloads/star.base64" If this is a faulty way of base64 encoding something, I'm open to suggestions for encoding to allow a JS decode function to work. – Dave May 31 '18 at 14:38
  • ok.. I have posted an answer. – Sreeragh A R Jun 01 '18 at 08:54

3 Answers3

0

Last edit: More publicity should made of this sentence from the 2015 related SO answer

The original solution (deprecated)

When mentioning atob, btoa, base64js and other libraries functions: save your time with a library and deprecate atob and btoa

Try base64.js.toByteArray with your data. Follow the link to the library Github Readme: it says it does exactly what you want, well, only that from and to.

Tested @1.3.0 succesfully with your data base64js.min.js on Chrome 66.0.3359.181

Tested @1.3.0 succesfully with your data in Nodejs @4.4.7

quote from the README:

base64js has three exposed functions, byteLength, toByteArray and fromByteArray, which both take a single argument.

  1. byteLength - Takes a base64 string and returns length of byte array
  2. toByteArray - Takes a base64 string and returns a byte array
  3. fromByteArray - Takes a byte array and returns a base64 string

I would also test original binary data against whatever file type/structure it is supposed to be/have, if you can access it.

Did you test the base64 string against base64, at first, is it a proper base64 string?

To be fair a code Example link and more information in the Github repo, when included as script in the client, use:

var byteArray = base64js.toByteArray(myBase64Str)

In Node, you would do:

var fs = require('fs')
var base64js =  require('base64-js')
fs.readFile('pathToMyBase64File', 'utf8', (err, data) => { // here 'utf8' is mandatory
  if (err) throw err;
  var byteArray = base64js.toByteArray(data)
  console.log(base64js.byteLength(data) == byteArray.length)
})

Important, myBase64File should be encoded with utf-8 w/BOM or it won´t work.

P.S. : I am not any contributor to this library, just a good tool for everybody to know, LICENSE MIT.

lucchi
  • 1,006
  • 6
  • 9
  • Can you elaborate a little more with a code sample? Are you saying "base64.js.toByteArray" will decode my base64 string taht was origianlly a binary data file? – Dave May 31 '18 at 14:12
  • This example taht you linekd to -- is this for a NodeJS script or for an in-browser application of the tool? I'm more interested in the in-browser application. – Dave May 31 '18 at 14:54
  • Both of them, for the moment I´ve been able to test your data with C# .NET and I get a length 5722 Array so data is OK. When I get an environment I´ll try with the JS lib – lucchi May 31 '18 at 15:22
  • I've just pated base64js.min.js in my console then called toByteArray over the pasted data and I got a beautiful Uint8Array(5722) [137, 80,... – lucchi May 31 '18 at 16:04
  • Ah this is good news. How did you invoke the toByteArray function? When I included "" on my page and then called "b64.toByteArray(myBase64Str)" using the example you posted, I get the error, "Uncaught TypeError: Cannot read property 'toByteArray' of undefined" – Dave May 31 '18 at 16:19
  • I agree it might not be the easiest example from the repo – lucchi May 31 '18 at 16:28
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/172177/discussion-between-lucchi-and-dave). – lucchi May 31 '18 at 16:29
0

As I already mentioned in the comments, the problem is with encoding. Your shared base64 string has a lot of newlines('\n') in it. Newlines are added (by cat) for user readability. But they cause troubles while decoding. If you try after removing all '\n' in your string and try atob(), it should be working.

To get base64 string without spaces or '\n'

In Linux

$ base64 -w 0 ~/Downloads/star.jpg >~/Downloads/star.base64

In Mac, you may try -A option in openssl.

$ openssl base64 -A -in ~/Downloads/star.jpg -out ~/Downloads/star.base64

Please try atob() with the resulting string (Copy directly from file not from cat output).

Note:I'm not a Mac user

Sreeragh A R
  • 2,871
  • 3
  • 27
  • 54
-1

You could try the following code:

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

Then you can create an async function that can do your job:

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

P.S: I've not checked this code for non-ASCII characters, so you need to try it

Ajay Kulkarni
  • 2,900
  • 13
  • 48
  • 97
  • 1
    THis only works if the thing that was encoed was originally a string, right? The thing I have encoded to a base64 string was binary data (think an image file). – Dave May 27 '18 at 16:39