zlib数据格式及解压缩实现

来源:互联网 发布:java springmvc框架 编辑:程序博客网 时间:2024/05/16 08:27

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   嬷碏  ! 


zip和apk文件

00000000   50 4B 03 04 14 00 00 00  08 00 A7 AD CF 48 D5 52   PK        Л螲誖

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殭



0x02 zlib在JAVA和c++的不同解压方法


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 be   allocated for processing, Z_STREAM_ERROR if an invalid compression   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the   version of the library linked do not match, or Z_ERRNO if there is   an 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, finish           compression 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 be   allocated for processing, Z_DATA_ERROR if the deflate data is   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and   the version of the library linked do not match, or Z_ERRNO if there   is 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;    }}




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 115邮箱无法登陆怎么办 群超时无法撤回怎么办 被加州大学撤回录取怎么办 ppt转码失败怎么办 苹果xicloud满了怎么办 小米note3不充电怎么办 网易云海外会员怎么办 百度云支付失败怎么办 信用卡输入密码错误怎么办 相机储存卡被锁怎么办 sd卡检测不到怎么办 手机图标闪退怎么办 电视看爱奇艺版权受限怎么办 王者荣耀重复id怎么办 拼多多资源位下架怎么办 百度云网络异常怎么办 公开课没上好怎么办 ios云备份失败怎么办 网易云登录异常怎么办? 阴阳师网易账号冻结怎么办 梦幻账号被冻结怎么办 手机忘记解锁密码怎么办 胃疼持续一天怎么办 胃痛一天一夜怎么办 孩子爱玩电脑怎么办 ipad不显示画面怎么办 正版win10换电脑怎么办 电脑系统不是正版怎么办 苹果平板进水了怎么办 华为平板进水了怎么办 三星平板进水了怎么办 笔记本cpu运行过高怎么办 微博永久性封号怎么办 电脑占用内存多怎么办 直播签约后悔了怎么办 移动宽带网络不稳定怎么办 股票帐号被锁定怎么办 电脑帐号锁定了怎么办 云校家帐号被锁定怎么办 qq音乐停止运行怎么办 做事效率低怎么办教案