参考:http://www.onicos.com/staff/iz/formats/gzip.html
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
gzip的文件解析
gzip文件格式可以分为四个部分:
- 文件头必选部分[10个字节]
- 文件头可选部分[0-N字节]
- 数据部分
- 文件尾部分[8个字节]
文件头必选部分(前10个字节)
前10个字节是必选的文件头部分
- bytes[0-1]: 文件标识符 0x1f, 0x8b
- bytes[2]: 压缩格式,取值说明(常用: 8-deflate类型)
- 0-Store存储不压缩
- 1-compress压缩
- 2-pack打包
- 3-lzh使用lzh算法压缩
- 4…7-保留reserve
- 8-deflate使用deflate算法压缩data部分
- bytes[3]: flags-字节中共有8比特,每个比特代表不同含义
- 0b00000001-压缩文件可能为文本格式
- 0b00000010-拆分多个压缩文件的其中一个部分,存在当前部分的序号
- 0b00000100-文件头中包含附加字段extra field.
- 0b00001000-文件头中包含文件名file name.
- 0b00010000-文件头中包含文件注释file comment.
- 0b00100000-文件是加密的,文件头中包含加密部分
- 0b11000000-6/7位保留reserve
- bytes[4-7]: 文件的修改时间(unix格式-4字节)
- bytes[8]: 附加flag(和bytes[2]压缩格式相关)
- bytes[9]: 操作系统类型OS Type, 取值说明参见下面,常用的有0x00-Windows,0x03-Unix/Linux
可选-附加文件头部分
可选部分和文件头中的字段取值对应:
例如文件头第4个字节bytes[3]取值8=0b00001000时,代表可选部分包含文件名file name。
- 2 Bytes: 拆分压缩包的第几个部分(从0开始, 1为第二个部分…)
- 2 Bytes + n Bytes: 附加字段的长度(最大2^16-1) + 附加字段
- n Bytes: 文件名file name,以0x00结尾
- n Bytes: 文件注释file comment, 以0x00结尾
- 12 Bytes: 加密信息
文件末尾部分:
- 4 Bytes: crc32 CRC校验码,压缩前数据的CRC校验码
- 4 Bytes: 文件的压缩前的原始长度大小对232取余,原始大小<4g时表示实际大小,原始大小>=4g时为对232取余后的值
注意:对于采用不同等级的压缩算法,压缩程度,CRC校验码都不受影响,原始大小也不受影响,所以此时后8位都应该一致的。
经过分析整理之后,觉得原来不够熟悉的gzip格式也变得可爱了起来。
附录-文件头第10个字节-操作系统类型
操作系统类型(OS Type):
0x00 Windows系列系统 FAT filesystem(MS-DOS, OS/2, NT/Win32)
0x01 Amiga
0x02 VMS (or OpenVMS)
0x03 Unix/Linux系列系统/Mac下命令终端压缩也使用该类型
0x04 VM/CMS
0x05 Atari TOS
0x06 HPFS filesystem (OS/2, NT)
0x07 Macintosh
0x08 Z-System
0x09 CP/M
0x0a TOPS-20
0x0b NTFS filesystem (NT)
0x0c QDOS
0x0d Acorn RISCOS
0xff unknown
使用zlib生成gzip文件样例
zlib是c/c++程序中经常用的gzip文件生成和解压库,效率很高。
从官方下载源码,使用cmake生成工程文件,编译即可得到库文件。
下面是一个压缩的样例代码:
#include "zlib.h"
...
auto file = gzopen(fname, "wb");
if (file == NULL) {
fprintf(stderr, "gzopen error\n");
exit(1);
}
int err;
if (gzwrite(file, buffer, length) != length){
fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err));
exit(1);
}
gzclose(file);
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)