Skip to content

Instantly share code, notes, and snippets.

@arq5x arq5x/test.sh
Last active Nov 30, 2019

Embed
What would you like to do?
Compress and then Decompress a string with zlib.
# compile
$ g++ zlib-example.cpp -lz -o zlib-example
# run
$ ./zlib-example
Uncompressed size is: 36
Uncompressed string is: Hello Hello Hello Hello Hello Hello!
----------
Compressed size is: 13
Compressed string is: x��H���W��G*2
----------
Uncompressed size is: 36
Uncompressed string is: Hello Hello Hello Hello Hello Hello!
#include <stdio.h>
#include <string.h> // for strlen
#include <assert.h>
#include "zlib.h"
// adapted from: http://stackoverflow.com/questions/7540259/deflate-and-inflate-zlib-h-in-c
int main(int argc, char* argv[])
{
// original string len = 36
char a[50] = "Hello Hello Hello Hello Hello Hello!";
// placeholder for the compressed (deflated) version of "a"
char b[50];
// placeholder for the UNcompressed (inflated) version of "b"
char c[50];
printf("Uncompressed size is: %lu\n", strlen(a));
printf("Uncompressed string is: %s\n", a);
printf("\n----------\n\n");
// STEP 1.
// deflate a into b. (that is, compress a into b)
// zlib struct
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
// setup "a" as the input and "b" as the compressed output
defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator
defstream.next_in = (Bytef *)a; // input char array
defstream.avail_out = (uInt)sizeof(b); // size of output
defstream.next_out = (Bytef *)b; // output char array
// the actual compression work.
deflateInit(&defstream, Z_BEST_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);
// This is one way of getting the size of the output
printf("Compressed size is: %lu\n", strlen(b));
printf("Compressed string is: %s\n", b);
printf("\n----------\n\n");
// STEP 2.
// inflate b into c
// zlib struct
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
// setup "b" as the input and "c" as the compressed output
infstream.avail_in = (uInt)((char*)defstream.next_out - b); // size of input
infstream.next_in = (Bytef *)b; // input char array
infstream.avail_out = (uInt)sizeof(c); // size of output
infstream.next_out = (Bytef *)c; // output char array
// the actual DE-compression work.
inflateInit(&infstream);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);
printf("Uncompressed size is: %lu\n", strlen(c));
printf("Uncompressed string is: %s\n", c);
// make sure uncompressed is exactly equal to original.
assert(strcmp(a,c)==0);
return 0;
}
@Barium

This comment has been minimized.

Copy link

Barium commented May 25, 2014

Is strlen really the right way to find size of compressed data? Can't the compressed data contain null-bytes? (line: 45)

@hitxiang

This comment has been minimized.

Copy link

hitxiang commented May 28, 2014

strlen should be replaced by infstream.total_out
printf("Uncompressed size is: %lu\n", infstream.total_out);
printf("Uncompressed string is: %.*s\n", infstream.total_out, c);

@YF-Tung

This comment has been minimized.

Copy link

YF-Tung commented Aug 22, 2016

Thanks a lot for the comment of @hitxiang, it's really helpful.
line 45 should be
printf("Compressed size is: %lu\n", defstream.total_out);

@gustavo4passos

This comment has been minimized.

Copy link

gustavo4passos commented Jun 6, 2018

I was looking for a quick example and found this.
Very helpful, thanks!

@ankitpateledu

This comment has been minimized.

Copy link

ankitpateledu commented Dec 1, 2018

I have modified your code to use random string by merging another example i found for random string generation; i found that with random string generated the compression doesn't work; meaning compressed and uncompressed length are same ; furthermore compressing compressed string always results in 3 less chars from tail . with default "hello" string as in original example it does compress and results are identical as you have shown.

do you see any reason, why this code should fail for random strings?

#include <stdio.h> 
#include <string.h>  // for strlen
#include <assert.h>
#include "zlib.h"
//#include <random.h>
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
// adapted from: http://stackoverflow.com/questions/7540259/deflate-and-inflate-zlib-h-in-c

static const char alphanum[] =
"0123456789"
"!@#$%^&*"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";

int stringLength = sizeof(alphanum) - 1;

int length = 50;

int main(int argc, char* argv[])
{
    // original string len = 36
    //char a[50] = "Hello Hello Hello Hello Hello Hello!";
    char a[length];
    // placeholder for the compressed (deflated) version of "a" 
    char b[length];

    // placeholder for the UNcompressed (inflated) version of "b"
    char c[length];


    srand(time(0));
//std::string a;
    for(unsigned int j = 0; j < 1; ++j)
    {
        //a = "";
        for(unsigned int i = 0; i < length ; ++i)
        {
        a[i]= alphanum[rand() % stringLength];

        }
                //char a[50]="Hello Hello Hello Hello Hello Hello!";
                printf("Uncompressed size is: %lu\n", strlen(a));
                printf("Uncompressed string is: %s\n", a);


                printf("\n----------\n\n");

                // STEP 1.
                // deflate a into b. (that is, compress a into b)

                // zlib struct
                z_stream defstream;
                defstream.zalloc = Z_NULL;
                defstream.zfree = Z_NULL;
                defstream.opaque = Z_NULL;
                // setup "a" as the input and "b" as the compressed output
                defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator
                defstream.next_in = (Bytef *)a; // input char array
                defstream.avail_out = (uInt)sizeof(b); // size of output
                defstream.next_out = (Bytef *)b; // output char array

                // the actual compression work.
                deflateInit(&defstream, Z_BEST_COMPRESSION);
                deflate(&defstream, Z_FINISH);
                deflateEnd(&defstream);
  // This is one way of getting the size of the output
                printf("Compressed size is: %lu\n", strlen(b));
                printf("Compressed string is: %s\n", b);


                printf("\n----------\n\n");
		// STEP 2.
    // inflate b into c
    // zlib struct
    z_stream infstream;
    infstream.zalloc = Z_NULL;
    infstream.zfree = Z_NULL;
    infstream.opaque = Z_NULL;
    // setup "b" as the input and "c" as the compressed output
    infstream.avail_in = (uInt)((char*)defstream.next_out - b); // size of input
    infstream.next_in = (Bytef *)b; // input char array
    infstream.avail_out = (uInt)sizeof(c); // size of output
    infstream.next_out = (Bytef *)c; // output char array
     
    // the actual DE-compression work.
    inflateInit(&infstream);
    inflate(&infstream, Z_NO_FLUSH);
    inflateEnd(&infstream);
     
    printf("Uncompressed size is: %lu\n", strlen(c));
    printf("Uncompressed string is: %s\n", c);
    

    // make sure uncompressed is exactly equal to original.
               
        }
        return 0;
}

and results are

 ./c.out 
Uncompressed size is: 50
Uncompressed string is: i5dY0LNq4^yilrkQqJYuW037$u^CDcw^hlzu^NwNou%Zx!8zfg

----------

Compressed size is: 50
706W)�svI.���*���/U��P��4M�4�+4���)�,�

----------

Uncompressed size is: 47
Uncompressed string is: i5dY0LNq4^yilrkQqJYuW037$u^CDcw^hlzu^NwNou%Zx!8

@pnhathung

This comment has been minimized.

Copy link

pnhathung commented Dec 11, 2018

Your length of array should be 51.

@jasonchristopherchandra

This comment has been minimized.

Copy link

jasonchristopherchandra commented Jan 12, 2019

does this run on windows ?

@shaheerakr

This comment has been minimized.

Copy link

shaheerakr commented May 3, 2019

when i am running this code this in giving me this error
error C2275: 'z_stream' : illegal use of this type as an expression

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.