Search code examples
javascriptgzippako

I want to decompress a GZIP string with JavaScript


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


Solution

  • 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>