【C/C++】C实现gzip格式的压缩与解压Demo

参考链接: 

http://www.codeproject.com/Questions/341319/C-Decompress-Gzipped-http-response

http://www.cppblog.com/woaidongmao/archive/2011/06/05/148089.html

http://stackoverflow.com/questions/13762918/setup-zlib-to-generate-gzipped-data

基于原有的代码整理后, 实现基础的gzip格式字节流压缩与解压, 代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
 
// gzCompress: do the compressing
int gzCompress(const char *src, int srcLen, char *dest, int destLen)
{
	z_stream c_stream;
	int err = 0;
	int windowBits = 15;
	int GZIP_ENCODING = 16;
 
	if(src && srcLen > 0)
	{
		c_stream.zalloc = (alloc_func)0;
		c_stream.zfree = (free_func)0;
		c_stream.opaque = (voidpf)0;
		if(deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 
                    windowBits | GZIP_ENCODING, 8, Z_DEFAULT_STRATEGY) != Z_OK) return -1;
		c_stream.next_in  = (Bytef *)src;
		c_stream.avail_in  = srcLen;
		c_stream.next_out = (Bytef *)dest;
		c_stream.avail_out  = destLen;
		while (c_stream.avail_in != 0 && c_stream.total_out < destLen) 
		{
			if(deflate(&c_stream, Z_NO_FLUSH) != Z_OK) return -1;
		}
        	if(c_stream.avail_in != 0) return c_stream.avail_in;
		for (;;) {
			if((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END) break;
			if(err != Z_OK) return -1;
		}
		if(deflateEnd(&c_stream) != Z_OK) return -1;
		return c_stream.total_out;
	}
	return -1;
}
 
// gzDecompress: do the decompressing
int gzDecompress(const char *src, int srcLen, const char *dst, int dstLen){
	z_stream strm;
	strm.zalloc=NULL;
	strm.zfree=NULL;
	strm.opaque=NULL;
	 
	strm.avail_in = srcLen;
	strm.avail_out = dstLen;
	strm.next_in = (Bytef *)src;
	strm.next_out = (Bytef *)dst;
	 
	int err=-1, ret=-1;
	err = inflateInit2(&strm, MAX_WBITS+16);
	if (err == Z_OK){
	    err = inflate(&strm, Z_FINISH);
	    if (err == Z_STREAM_END){
	        ret = strm.total_out;
	    }
	    else{
	        inflateEnd(&strm);
	        return err;
	    }
	}
	else{
	    inflateEnd(&strm);
	    return err;
	}
	inflateEnd(&strm);
	return err;
}
 
int testCompress(char* src)
{
	printf("=====================================================\n");
	int size_src = strlen(src);
	char* compressed = malloc(size_src*2);
	memset(compressed, 0, size_src*2);
	printf("to compress src: %s\n", src);
	printf("to compress src size: %d\n", size_src);
 
	int gzSize = gzCompress(src, size_src, compressed, size_src*2);
	if (gzSize <= 0)
	{
		printf("compress error.\n");
		return -1;
	}
	printf("compressed: ");
	int i = 0;
	for (; i<gzSize; ++i)
	{
		printf("%02x ", compressed[i]);
	}
	printf("\ncompressed size: %d\n", gzSize);
 
	char* uncompressed = malloc(size_src*2);
	memset(uncompressed, 0, size_src*2);
	int ret = gzDecompress(compressed, gzSize, uncompressed, size_src*2);
	printf("uncompressed: %s\n", uncompressed);
	printf("uncompressed size: %zu\n", strlen(uncompressed));
 
	free(compressed);
	free(uncompressed);
	return 0;
}

int main() {	
	char* src = "just for test, dd, dd, dd";
	testCompress(src);

	char* src2 ="just for test, jkljasdkljaskdjlkasdnklawhekljhwalkejwqkljeklqwjekldjaskldjkasdkjaskldjawioeuqw890e4uwiodjaskljdlasjdkasjdlkjaskldjaslkdjlaskjdklasjdklasjkldjaskldjaskldjklasjdlasjkdjlaskdj";
	testCompress(src2);

	return 0;
}

运行效果:

xiaomo@xiaomo:/data/test$ gcc a.c -o gztest -lz
xiaomo@xiaomo:/data/test$ ./gztest 
=====================================================
to compress src: just for test, dd, dd, dd
to compress src size: 25
compressed: 1f ffffff8b 08 00 00 00 00 00 00 03 ffffffcb 2a 2d 2e 51 48 ffffffcb 2f 52 28 49 2d 2e ffffffd1 51 48 49 ffffff81 61 00 33 ffffffc3 ffffffe2 fffffff3 19 00 00 00 
compressed size: 38
uncompressed: just for test, dd, dd, dd
uncompressed size: 25
=====================================================
to compress src: just for test, jkljasdkljaskdjlkasdnklawhekljhwalkejwqkljeklqwjekldjaskldjkasdkjaskldjawioeuqw890e4uwiodjaskljdlasjdkasjdlkjaskldjaslkdjlaskjdklasjdklasjkldjaskldjaskldjklasjdlasjkdjlaskdj
to compress src size: 188
compressed: 1f ffffff8b 08 00 00 00 00 00 00 03 45 ffffff8d 41 0e ffffffc3 30 08 04 ffffffbf ffffffe2 07 fffffff4 ffffff90 43 0e ffffffcd 73 ffffff90 20 4a 01 35 72 ffffffb1 ffffffc5 fffffff7 0b 76 ffffff94 5c 46 2c 3b 02 ffffffee ffffffd6 ffffffca 7e fffffffe 4a 23 6b ffffffaf ffffffc2 ffffffa2 0c ffffff86 ffffff83 ffffff82 ffffffac 12 ffffffe1 2b 0a 7e 50 ffffffec 0e 07 15 62 ffffffaf 31 47 ffffffae ffffff9e ffffffc4 54 ffffff83 ffffffa9 ffffffca 35 ffffff83 7f 4e ffffffea ffffffd5 ffffffdf ffffffdb 42 6b ffffff8f 30 25 46 05 63 ffffff94 ffffff84 ffffffde ffffffae 69 7e ffffff8a 10 ffffffcd ffffffec ffffff93 ffffffcf ffffffe1 ffffffeb fffffffc ffffffa8 46 33 6d ffffffe4 3f ffffffb7 1f ffffffa8 ffffffae ffffffbc 00 00 00 
compressed size: 126
uncompressed: just for test, jkljasdkljaskdjlkasdnklawhekljhwalkejwqkljeklqwjekldjaskldjkasdkjaskldjawioeuqw890e4uwiodjaskljdlasjdkasjdlkjaskldjaslkdjlaskjdklasjdklasjkldjaskldjaskldjklasjdlasjkdjlaskdj
uncompressed size: 188

 

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值