zlib数据格式及解压缩实现
生活随笔
收集整理的這篇文章主要介紹了
zlib数据格式及解压缩实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
0x01 zlib和其他壓縮的魔術頭
一般來說壓縮文件都有個魔術頭,用于區分不同的壓縮文件對應不同的解壓縮算法。
7z文件:?
00000000 37 7A BC AF 27 1C 00 03 CD F7 CC 2E 66 6A 33 00 7z集' 枉?fj3
tar.xz文件
00000000 FD 37 7A 58 5A 00 00 04 E6 D6 B4 46 02 00 21 01 ?zXZ 嬤碏 !
rar文件 00000000 52 61 72 21 1A 07 00 CF 90 73 00 00 0D 00 00 00 Rar! ?s
zlib文件
00000000 78 01 ED 9D 0B 94 1C 57 79 E7 AB A6 9F 33 9A 99 x ? ?Wy绔3殭
JAVA:
public static byte[] decompress(byte[] compress) throws Exception { ByteArrayInputStream bais = new ByteArrayInputStream(compress); InflaterInputStream iis = new InflaterInputStream(bais); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int c = 0; byte[] buf = new byte[BUFFER_SIZE]; while (true) { c = iis.read(buf); if (c == EOF) break; baos.write(buf, 0, c); } baos.flush(); return baos.toByteArray(); }C++ #include <stdio.h> #include <string.h> #include <assert.h> #include "zlib.h"#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) # include <fcntl.h> # include <io.h> # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) #else # define SET_BINARY_MODE(file) #endif#define CHUNK 16384/* Compress from file source to file dest until EOF on source.def() returns Z_OK on success, Z_MEM_ERROR if memory could not beallocated for processing, Z_STREAM_ERROR if an invalid compressionlevel is supplied, Z_VERSION_ERROR if the version of zlib.h and theversion of the library linked do not match, or Z_ERRNO if there isan error reading or writing the files. */ int def(FILE *source, FILE *dest, int level) {int ret, flush;unsigned have;z_stream strm;unsigned char in[CHUNK];unsigned char out[CHUNK];/* allocate deflate state */strm.zalloc = Z_NULL;strm.zfree = Z_NULL;strm.opaque = Z_NULL;ret = deflateInit(&strm, level);if (ret != Z_OK)return ret;/* compress until end of file */do {strm.avail_in = fread(in, 1, CHUNK, source);if (ferror(source)) {(void)deflateEnd(&strm);return Z_ERRNO;}flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;strm.next_in = in;/* run deflate() on input until output buffer not full, finishcompression if all of source has been read in */do {strm.avail_out = CHUNK;strm.next_out = out;ret = deflate(&strm, flush); /* no bad return value */assert(ret != Z_STREAM_ERROR); /* state not clobbered */have = CHUNK - strm.avail_out;if (fwrite(out, 1, have, dest) != have || ferror(dest)) {(void)deflateEnd(&strm);return Z_ERRNO;}} while (strm.avail_out == 0);assert(strm.avail_in == 0); /* all input will be used *//* done when last data in file processed */} while (flush != Z_FINISH);assert(ret == Z_STREAM_END); /* stream will be complete *//* clean up and return */(void)deflateEnd(&strm);return Z_OK; }/* Decompress from file source to file dest until stream ends or EOF.inf() returns Z_OK on success, Z_MEM_ERROR if memory could not beallocated for processing, Z_DATA_ERROR if the deflate data isinvalid or incomplete, Z_VERSION_ERROR if the version of zlib.h andthe version of the library linked do not match, or Z_ERRNO if thereis an error reading or writing the files. */ int inf(FILE *source, FILE *dest) {int ret;unsigned have;z_stream strm;unsigned char in[CHUNK];unsigned char out[CHUNK];/* allocate inflate state */strm.zalloc = Z_NULL;strm.zfree = Z_NULL;strm.opaque = Z_NULL;strm.avail_in = 0;strm.next_in = Z_NULL;ret = inflateInit(&strm);if (ret != Z_OK)return ret;/* decompress until deflate stream ends or end of file */do {strm.avail_in = fread(in, 1, CHUNK, source);if (ferror(source)) {(void)inflateEnd(&strm);return Z_ERRNO;}if (strm.avail_in == 0)break;strm.next_in = in;/* run inflate() on input until output buffer not full */do {strm.avail_out = CHUNK;strm.next_out = out;ret = inflate(&strm, Z_NO_FLUSH);assert(ret != Z_STREAM_ERROR); /* state not clobbered */switch (ret) {case Z_NEED_DICT:ret = Z_DATA_ERROR; /* and fall through */case Z_DATA_ERROR:case Z_MEM_ERROR:(void)inflateEnd(&strm);return ret;}have = CHUNK - strm.avail_out;if (fwrite(out, 1, have, dest) != have || ferror(dest)) {(void)inflateEnd(&strm);return Z_ERRNO;}} while (strm.avail_out == 0);/* done when inflate() says it's done */} while (ret != Z_STREAM_END);/* clean up and return */(void)inflateEnd(&strm);return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; }/* report a zlib or i/o error */ void zerr(int ret) {fputs("zpipe: ", stderr);switch (ret) {case Z_ERRNO:if (ferror(stdin))fputs("error reading stdin\n", stderr);if (ferror(stdout))fputs("error writing stdout\n", stderr);break;case Z_STREAM_ERROR:fputs("invalid compression level\n", stderr);break;case Z_DATA_ERROR:fputs("invalid or incomplete deflate data\n", stderr);break;case Z_MEM_ERROR:fputs("out of memory\n", stderr);break;case Z_VERSION_ERROR:fputs("zlib version mismatch!\n", stderr);} }/* compress or decompress from stdin to stdout */ int main(int argc, char **argv) {int ret;/* avoid end-of-line conversions */SET_BINARY_MODE(stdin);SET_BINARY_MODE(stdout);/* do compression if no arguments */if (argc == 1) {ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);if (ret != Z_OK)zerr(ret);return ret;}/* do decompression if -d specified */else if (argc == 2 && strcmp(argv[1], "-d") == 0) {ret = inf(stdin, stdout);if (ret != Z_OK)zerr(ret);return ret;}/* otherwise, report usage */else {fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);return 1;} }
總結
以上是生活随笔為你收集整理的zlib数据格式及解压缩实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 砥志研思SVM(二) 拉格朗日乘子法与
- 下一篇: 外设驱动库开发笔记5:AD7705系列A