Jon Sud
Jon Sud

Reputation: 11641

How atob doesn't convert from Buffer with base64?

I have data that I encrypt using lz-string package.

I also convert the result to base64 and using atob() function to convert from base64.

The problem is atob() doesn't work as expected but Buffer.from(b64, 'base64').toString(); does.

Why? how do I fix that? I need to use atob in the client side (the Buffer is not exist in the browser).

StackBlitz example

Upvotes: 4

Views: 2091

Answers (2)

Touffy
Touffy

Reputation: 6561

The more effective (see below) option would be, if your LZ library supports it, to not interpret the base64-encoded buffer as a string and pass it to the library as a Uint8Array directly. You can do that with

const buffer = Uint8Array.from(atob(b64), c => c.charCodeAt(0))

And then if you really need a string, you can use a TextDecoder, which is a bit less hacky than Shlomi's admittedly very nice solution:

const text = new TextDecoder().decode(buffer)

There are a couple reasons why using a TypedArray is more effective and an implementation of LZ should really work on them rather than strings (and probably use WebAssembly). Obviously you skip the UTF-8 decoding, but the more significant reason is because in JavaScript, strings are represented in memory as UTF-16, so each character takes at least 2 bytes (exactly 2 bytes in the case of a binary string) whereas the Uint8Array — as the name suggests — only uses one byte per item.

Upvotes: 0

Shlomi Levi
Shlomi Levi

Reputation: 3305

Use decodeURIComponent and escape to convert to UTF-8.

const non64 = decodeURIComponent(escape(window.atob( b64 )));

Upvotes: 3

Related Questions