Search code examples
javascriptnode.jsarraysencodingcompression

Decompression of string not works properly


I am writing a code to prepare a compressed encoded string for my qr-code. I am using TextEncoder for encoding of my data into Uint8Array and further compressing to reduce the size using the brotli library. At some point I want to concatenate the compressed encoded string into the qr-code to have random value for which I am decoding it using TextDecoder and using the random string value to build my QR-code. The problem is that the string I get after decoding I am unable to get to the original string If i perform encode -> decompress - decode.

const encodedDetails = new TextEncoder().encode(JSON.stringify(this.studentDetails, null, 0)); // encoded in Uint8Array
const compressedEncodedDetails = await compress(encodedDetails); // compress Uint8Array into Uint8Array
const decodeData = new TextDecoder().decode(compressedEncodedDetails); // decoding Uint8Array into string to create QR code

const encode_decodeData = new TextEncoder().encode(decodeData); // encoding string into Uint8Array 
const de_compress_compressedData = await decompress(encode_decodeData); // decompressing
const orignalData = new TextDecoder().decode(de_compress_compressedData); // decoding the original value

console.log('+++++ encoded data 1', encodedDetails);
console.log('+++++ compressed data 2', compressedEncodedDetails);
console.log('++++++ decodeData data 3', decodeData);
console.log('++++++ encode_decodeData data 4', encode_decodeData);
console.log('++++++ d_compress_compressedData data 5', de_compress_compressedData);
console.log('++++++ d_compress_compressedData data 6', orignalData);

I don't really getting it where's the problem coming up, any hint or suggestion would be beneficial.

Here is the console log for enter image description here


Solution

  • You are trying to decode a compressed binary blob as if it were a text. This is why it is not recoverable when trying to decompress it.

    You could consider keeping the data as binary (Uint8Array) until you are ready to decompress it. Since you are trying to embed the data into a QR code, you could consider base64 encoding:

    const encodedDetails = new TextEncoder().encode(JSON.stringify(this.studentDetails, null, 0)); // encoded in Uint8Array
    const compressedEncodedDetails = await compress(encodedDetails); // compress Uint8Array into Uint8Array
    
    // Convert to Base64 for QR code
    const base64Encoded = btoa(String.fromCharCode.apply(null, compressedEncodedDetails));
    // Embed 'base64Encoded' into your QR code
    
    // Later, when you read the QR code, you can decode the base64 string back into binary for decompression
    const decodeData = atob(base64Encoded);
    const byteArray = new Uint8Array(decodeData.length).map((_, i) => decodeData.charCodeAt(i)); 
    
    const de_compress_compressedData = await decompress(byteArray); // decompressing
    const originalData = new TextDecoder().decode(de_compress_compressedData); // decoding the original value
    
    console.log('++++++ original data', originalData);