convert base64 to json in javaScript
Asked Answered
W

1

2

For example, I have a base64 code like this

const base64 = "H4sIAAAAAAAEAO2b0W6CMBSGz6MsXm+JUKi6N9gzLLsw4jYTo0bJbpa9+44Ig0J7kBW0PSENNG2B9vtjw09PfYVvmMAGEjw/QwiPmKdYTmEL66xuAics7eGI5QcI4AmPSXbdAZZZ7Q7bX/InBFlLeYdaf37mFx7bSl2C5ROs8OoNPvHc9x6feOk5BAFR3tsK65O/MQmQEGP+g21VAgFzI8O5hx183Gz0zT5VBrW9SbLwkiTQsEQw9ZQl1NKY54nrNJf51CQS7IgidkQxOyLJjmjGjsjP9ylF5Ot71UQUe/x2NREFzIgkO88g2XkGyc4zSHaeQXrqGUTOVD3r+Xx0ECpXF1rKXaj382OnfMi92dX+h1ViZvAvByUtG+lYS+ta2ikpraX7qLnEcgLveX4530Jhyk+V95cjK/N7//76UEylovXTqUd5t1G9NvUonziq16Ye5UlH9drUo/zvqF6bepTXHtWj1Ztf6W3/q16x6nOdfqGH+l3nj0f9TPoNO3sj9vpRX+Kjfu36Detcivg4X/2G9S789Rv2q63YacJXv2G/27jrZ1avupcqJBQKe9WnWBtqcoss8qGPw9lErfodf1+RRZuolZtENlErN4lsolZuEtlErdwksolTuUlks9PFTSKbnS4uEkmrnS5uEtnsdHGRaE4S2fvG/pldco2LgVe9RAf1xA3UW8Entm6zUdS1CHC26+e7mW/R6as2aiXUjVk/UupXH2f7KNvXw6ed1oRi6xkd5f+heINfmSW/7QgyAAA="

Now I want to convert this to json

I have tried to convert this base64 to object But I don't know if it's true or not but still my problem is not solved because I can't do anything with that json

const base64 = "H4sIAAAAAAAEAO2b0W6CMBSGz6MsXm+JUKi6N9gzLLsw4jYTo0bJbpa9+44Ig0J7kBW0PSENNG2B9vtjw09PfYVvmMAGEjw/QwiPmKdYTmEL66xuAics7eGI5QcI4AmPSXbdAZZZ7Q7bX/InBFlLeYdaf37mFx7bSl2C5ROs8OoNPvHc9x6feOk5BAFR3tsK65O/MQmQEGP+g21VAgFzI8O5hx183Gz0zT5VBrW9SbLwkiTQsEQw9ZQl1NKY54nrNJf51CQS7IgidkQxOyLJjmjGjsjP9ylF5Ot71UQUe/x2NREFzIgkO88g2XkGyc4zSHaeQXrqGUTOVD3r+Xx0ECpXF1rKXaj382OnfMi92dX+h1ViZvAvByUtG+lYS+ta2ikpraX7qLnEcgLveX4530Jhyk+V95cjK/N7//76UEylovXTqUd5t1G9NvUonziq16Ye5UlH9drUo/zvqF6bepTXHtWj1Ztf6W3/q16x6nOdfqGH+l3nj0f9TPoNO3sj9vpRX+Kjfu36Detcivg4X/2G9S789Rv2q63YacJXv2G/27jrZ1avupcqJBQKe9WnWBtqcoss8qGPw9lErfodf1+RRZuolZtENlErN4lsolZuEtlErdwksolTuUlks9PFTSKbnS4uEkmrnS5uEtnsdHGRaE4S2fvG/pldco2LgVe9RAf1xA3UW8Entm6zUdS1CHC26+e7mW/R6as2aiXUjVk/UupXH2f7KNvXw6ed1oRi6xkd5f+heINfmSW/7QgyAAA="

Convert to string using atob

let convertString = atob(base64);

Convert string to ArrayBuffer

let arrayBuffer = new ArrayBuffer(convertString.length);
let uint8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < convertString.length; i++) {
    uint8Array[i] = convertString.charCodeAt(i);
}

Now, using the pako library, it becomes an array that contains an object, but there is a space between all the characters, and this is very strange.

let inflatedData = pako.inflate(uint8Array, { to: 'string' });
console.log(inflatedData)

This is the image of the inflatedData console output

enter image description here

A point that might help: the data that comes from the database is typed as varBinary(Max).

Waltman answered 28/1 at 6:56 Comment(12)
Have you made an effort? Show what you've tried. Also, that base64 encoded string does not seem to result in any kind of human readable content.Anabaptist
Yes, I have done a number of things I will definitely post the output right now Thank you in advanceWaltman
What you have there is JSON that has been gzipped and then base64 encoded, which is very strange. gzip makes it smaller, and base64 makes it bigger. So, you can use the base64 module to extract the gzip, and the gzip module to extract the JSON.Bregenz
@TimRoberts I edited the question and I think I did what you said, but the output does not work as you can see in the picture.Waltman
Looks like it's encoded oddly, those aren't just extra spaces. There's an extra \u0 between every byte. You can test by running echo "that string" | base64 --decode | gunzip - . It'' show as (probably) intended in the terminal, but if you add a | vim -, it'll show with the extra chars. So you'll need to do something like fixEncoding(gunzip(base64Decode(thatString))). Or fix whereever you're getting that data from.Ribbing
@ZacAnger If I understand your meaning correctly, you say to test with this method to see if it works or not "base64 string" | base64 --decode | gunzipWaltman
Are you sure the base 64 encoded string is an encoded json string?Sacristy
@OmarHossamAhmed This code was given to me by someone who works on the database and she says that inside this is an array of objectsWaltman
Well then an atob followed by a JSON.parse should be sufficient, but put it in a try/catch just in case.Sacristy
Also one side note if base-64 is used for encryption that is not really secure. Just saying if that was the intention...Sacristy
@OmarHossamAhmed Well, I did what you said But it doesn't work at all It can be tested on the console as well. If you don't mind, please do a test yourself. I will be gratefulWaltman
@davoodbeheshti I'm saying that's how you can verify that what I said is correct, but that's not the whole solution. I figured out the encoding though, it's utf16le (or maybe ucs2). I'll post an answer.Ribbing
R
2

This string is a little funky. It's JSON in UTF16-LE, gzipped, then base64 encoded. In Node:

const base64 = "H4sIAAAAAAAEAO2b0W6CMBSGz6MsXm+JUKi6N9gzLLsw4jYTo0bJbpa9+44Ig0J7kBW0PSENNG2B9vtjw09PfYVvmMAGEjw/QwiPmKdYTmEL66xuAics7eGI5QcI4AmPSXbdAZZZ7Q7bX/InBFlLeYdaf37mFx7bSl2C5ROs8OoNPvHc9x6feOk5BAFR3tsK65O/MQmQEGP+g21VAgFzI8O5hx183Gz0zT5VBrW9SbLwkiTQsEQw9ZQl1NKY54nrNJf51CQS7IgidkQxOyLJjmjGjsjP9ylF5Ot71UQUe/x2NREFzIgkO88g2XkGyc4zSHaeQXrqGUTOVD3r+Xx0ECpXF1rKXaj382OnfMi92dX+h1ViZvAvByUtG+lYS+ta2ikpraX7qLnEcgLveX4530Jhyk+V95cjK/N7//76UEylovXTqUd5t1G9NvUonziq16Ye5UlH9drUo/zvqF6bepTXHtWj1Ztf6W3/q16x6nOdfqGH+l3nj0f9TPoNO3sj9vpRX+Kjfu36Detcivg4X/2G9S789Rv2q63YacJXv2G/27jrZ1avupcqJBQKe9WnWBtqcoss8qGPw9lErfodf1+RRZuolZtENlErN4lsolZuEtlErdwksolTuUlks9PFTSKbnS4uEkmrnS5uEtnsdHGRaE4S2fvG/pldco2LgVe9RAf1xA3UW8Entm6zUdS1CHC26+e7mW/R6as2aiXUjVk/UupXH2f7KNvXw6ed1oRi6xkd5f+heINfmSW/7QgyAAA="

const zlib = require('zlib') // the builtin, not the old npm package
const buf = Buffer.from(base64, 'base64')
const res = zlib.gunzipSync(buf).toString('utf16le')

console.log(JSON.parse(res))

The result is an array of objects that look like test data.


Per the comments, here's how it could work in the browser. This assumes pako, which is mentioned in the question:

import pako from 'pako'
const gzipped = atob(base64)

const toU = (d) =>
    new Uint8Array([...d]
        .map((c) => c.charCodeAt(0)))

const utf16 = pako.inflate(toU(gzipped), { to: 'string' })
const td = new TextDecoder('utf-16le')
const res = td.decode(toU(utf16))

console.log(JSON.parse(res))

There might be a more efficient way to do this, but it's very late, so I'm not able to see it right now.

Ribbing answered 28/1 at 9:15 Comment(3)
I did not have the zlib package I installed it now but it gives me this error (Error: Module not found: Error: Can't resolve './zlib_bindings' in ....) My project is Angular but I don't think it has anything to do with itWaltman
In Node, you don't need to install it, it's native. The zlib package on npm hasn't been upated in 12 years because there's a builtin module now. But that won't help if you're doing this client-side, you'd need to use browserify-zlib or something similar. I'll test and update my answer.Ribbing
Thank you very much, it was fixed and it worked fine, thank you This answer was approved and got a positive score, thank you very muchWaltman

© 2022 - 2024 — McMap. All rights reserved.