2

I have this GZIPed string: H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==

I created that with this website: http://www.txtwizard.net/compression

I have tried using pako to ungzip it.

import { ungzip } from 'pako';

const textEncoder = new TextEncoder();
const gzipedData = textEncoder.encode("H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==");
console.log('gzipeddata', gzipedData);
const ungzipedData = ungzip(gzipedData);
console.log('ungziped data', ungzipedData);

The issue is that Pako throws the error: incorrect header check

What am I missing here?

A JSbin

Mureinik
  • 297,002
  • 52
  • 306
  • 350
petur
  • 1,366
  • 3
  • 21
  • 42

2 Answers2

2

The "H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==" is a base64 encoded string, you first need to decode that into a buffer.

textEncoder.encode just encodes that base64 encoded string into a byte stream.

How to do that depend on whether you are in a browser or on nodejs.

node.js version

To convert the unzipped data to a string you further have use new TextDecoder().decode()

For node you will use Buffer.from(string, 'base64') to decode the base64 encoded string:

import { ungzip } from 'pako';

// decode the base64 encoded data
const gzipedData = Buffer.from("H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==", "base64");

console.log('gzipeddata', gzipedData);
const ungzipedData = ungzip(gzipedData);


console.log('ungziped data', new TextDecoder().decode(ungzipedData));

browser version

In the browser, you have to use atob, and you need to convert the decoded data to an Uint8Array using e.g. Uint8Array.from.

The conversion I used was taken from Convert base64 string to ArrayBuffer, you might need to verify if that really works in all cases.

// decode the base64 encoded data
const gezipedData = atob("H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==")
const gzipedDataArray = Uint8Array.from(gezipedData, c => c.charCodeAt(0))

console.log('gzipeddata', gzipedDataArray);
const ungzipedData = pako.ungzip(gzipedDataArray);


console.log('ungziped data', new TextDecoder().decode(ungzipedData));
<script src="https://cdnjs.cloudflare.com/ajax/libs/pako/2.0.4/pako.min.js"></script>
t.niese
  • 39,256
  • 9
  • 74
  • 101
  • 1
    Now I'm getting: `invalid stored block lengths` – petur Sep 14 '21 at 14:38
  • @petur where do you run that code (browser or node, what version of node or which browser). The first code snipped runs fine in `node` and the second one shows the correct output when I run it in the browser. – t.niese Sep 14 '21 at 14:39
  • I'm running it in the browser. ! I just replaced `Buffer.from` with `atob`, didn't realize I had to do both `atob` and `Uint8Array.from` Thanks! – petur Sep 14 '21 at 14:42
  • @petur The first one is the node version (node has `Buffer.from`). the second on is for the browser, there only `atob` exists and the result that call is not compatible with `pako` you need to convert it to an `Uint8Array` first, – t.niese Sep 14 '21 at 14:45
1

This string is base64-encoded.

You first need to decode it to a buffer:

const gzippedString = 'H4sIAAAAAAAA//NIzcnJVyguSUzOzi9LLUrLyS/XUSjJSMzLLlZIyy9SSMwpT6wsVshIzSnIzEtXBACs78K6LwAAAA==';
const gzippedBuffer = new Buffer(gzippedString, 'base64');

Then you can un(g)zip it:

const unzippedBuffer = ungzip(gzippedBuffer);

The result on ungzip is a Unit8Array. If you want to convert it back to a string you'll need to decode it again:

const unzippedString = new TextDecoder('utf8').decode(unzipped);
Mureinik
  • 297,002
  • 52
  • 306
  • 350