Reputation: 139
Here is how I compress binary string (char codes above 255) with pako:
var charData = xhr.responseText.split('').map(function(x){return x.charCodeAt(0);});
var binData = new Uint8Array(charData);
var data = pako.deflate(binData, {level:"9"});
Here is how I decompress data back:
var data2 = pako.inflate(xhr.responseText);
Now, how can I get original string in JavaScript from this object? I tried methods like this:
A.
pako.inflate(xhr.responseText, {to:"string"});
B.
String.fromCharCode.apply(null, data2);
C.
for (var i = 0, l = data2.length; i < l; i++)
{
result += String.fromCharCode(parseInt(array[i], 2));
}
All of these methods bring different data as JavaScript string than original. When I save decompressed pako.inflate(xhr.responseText) to a file (using functions with a.download) then dempressed file has exactly the same bytes as original file (so compression and decompression works correctly, without any byte modification).
Upvotes: 7
Views: 10814
Reputation: 712
Don't use charCodeAt
and fromCharCode
for this task, since they will fail if you have Unicode in your string.
For example, the following breaks the emojis.
// Encode
var charData = "cat 🐈 dog 🐕".split('').map(function(x){return x.charCodeAt(0);});
var array = new Uint8Array(charData);
// Decode
var result = "";
for (var i = 0; i < array.length; i++)
{
result += String.fromCharCode(array[i]);
}
Why? Because Javascript strings are stored as UTF-16, which leads to some characters being a pair of characters.
Instead, just use TextEncoder and TextDecoder, like @Ugur Abbasov recommended.
// Encode
const encoder = new TextEncoder();
const text = "your string goes here";
const binData = encoder.encode(text);
const compressedData = pako.deflate(binData, {level:"9"});
// Decode
const decoder = new TextDecoder();
const data2 = pako.inflate(compressedData);
const text2 = decoder.decode(data2);
Upvotes: 0
Reputation: 39
It isnt that hard. So just call class TextEncoder() and then encode method. For example
new TextEncoder().encode(JSON.stringify('Your object'))
For decode use just method decode.
Upvotes: 3
Reputation: 2672
I am just trying to do the same and found a way to convert Object to binary string and vice versa. I just create a two function that converts JSON Object to Binary String and Binary String to JSON Object viz. covertObjectToBinary and convertBinaryToObject.
let obj = {a:1}
function covertObjectToBinary(obj) {
let output = '',
input = JSON.stringify(obj) // convert the json to string.
// loop over the string and convert each charater to binary string.
for (i = 0; i < input.length; i++) {
output += input[i].charCodeAt(0).toString(2) + " ";
}
return output.trimEnd();
}
function convertBinaryToObject(str) {
var newBin = str.split(" ");
var binCode = [];
for (i = 0; i < newBin.length; i++) {
binCode.push(String.fromCharCode(parseInt(newBin[i], 2)));
}
let jsonString = binCode.join("");
return JSON.parse(jsonString)
}
console.log('covertObjectToBinary =>', covertObjectToBinary(obj))
console.log('convertBinaryToObject =>', convertBinaryToObject(covertObjectToBinary(obj)))
Upvotes: 2