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 嬷碏 !
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殭
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; }}
阅读全文
0 0
- zlib数据格式及解压缩实现
- Android实现zlib解压缩
- Zlib数据格式
- 采用ZLIB及MINIZIP进行文件解压缩及加解密
- 采用ZLIB及MINIZIP进行文件解压缩及加解密
- vb6中用zlib.dll实现压缩/解压缩字节数组
- Android上实现zlib解压缩的方法 Inflater用法
- Zlib库的使用实现对zip文件的解压缩
- java实现zlib压缩解压缩:文件、byte[]字节数组,数据流
- Zlib解压缩示例
- zlib压缩解压缩文件
- lua 解压缩文件zlib
- android ZLib压缩/解压缩
- ZLib 解压缩工具
- 解压缩zlib用法简单说明
- 使用zlib压缩解压缩文件
- zlib minizip 压缩与解压缩
- java压缩,解压缩zlib文件
- VUE+WebPack精美游戏设计:实现像微信红包打开时钱币转动的动画精灵和页面数据的本地存储
- HDU 1789(贪心)
- 上传图片文件用PHP处理
- 基于stm32串口环形缓冲队列处理机制—入门级(单字节)
- Android Parcelable问题
- zlib数据格式及解压缩实现
- struts2+hibernate+ehcache二级缓存(注解方式)
- getFilesDir()与getExternalFilesDir()的区别
- 用C/C++代码检测ip能否ping通(配合awk和system可以做到批量检测)
- 分布式消息队列
- python自动测试
- 【Scikit-Learn 中文文档】模型选择:选择估计量及其参数
- 深入理解Java垃圾回收机制
- 让机器帮你写博客-机器学习实战