ZIP format
Byte order: Little-endian
[Local file header + Compressed data [+ Extended local header]?]*
[Central directory]*
[End of central directory record]
Offset Length Contents
0 4 bytes Local file header signature (0x04034b50)
4 2 bytes Version needed to extract
6 2 bytes General purpose bit flag
8 2 bytes Compression method
10 2 bytes Last mod file time
12 2 bytes Last mod file date
14 4 bytes CRC-32
18 4 bytes Compressed size (n)
22 4 bytes Uncompressed size
26 2 bytes Filename length (f)
28 2 bytes Extra field length (e)
(f)bytes Filename
(e)bytes Extra field
(n)bytes Compressed data
Offset Length Contents
0 4 bytes Extended Local file header signature (0x08074b50)
4 4 bytes CRC-32
8 4 bytes Compressed size
12 4 bytes Uncompressed size
Offset Length Contents
0 4 bytes Central file header signature (0x02014b50)
4 2 bytes Version made by
6 2 bytes Version needed to extract
8 2 bytes General purpose bit flag
10 2 bytes Compression method
12 2 bytes Last mod file time
14 2 bytes Last mod file date
16 4 bytes CRC-32
20 4 bytes Compressed size
24 4 bytes Uncompressed size
28 2 bytes Filename length (f)
30 2 bytes Extra field length (e)
32 2 bytes File comment length (c)
34 2 bytes Disk number start
36 2 bytes Internal file attributes
38 4 bytes External file attributes
42 4 bytes Relative offset of local header
46 (f)bytes Filename
(e)bytes Extra field
(c)bytes File comment
0 - The file is stored (no compression)
1 - The file is Shrunk
2 - The file is Reduced with compression factor 1
3 - The file is Reduced with compression factor 2
4 - The file is Reduced with compression factor 3
5 - The file is Reduced with compression factor 4
6 - The file is Imploded
7 - Reserved for Tokenizing compression algorithm
8 - The file is Deflated
Offset Length Contents
0 4 bytes End of central dir signature (0x06054b50)
4 2 bytes Number of this disk
6 2 bytes Number of the disk with the start of the central directory
8 2 bytes Total number of entries in the central dir on this disk
10 2 bytes Total number of entries in the central dir
12 4 bytes Size of the central directory
16 4 bytes Offset of start of central directory with respect to the starting disk number
20 2 bytes zipfile comment length (c)
22 (c)bytes zipfile comment
单看上面的介绍不会有多少印象,也可能不知道它在说什么,
下面以一个android 的apk 来举例分析, 它包含289个文件,文件大小7.4M,是个真枪实弹的东西。
看完实例,结合上面介绍,就理解了数据结构!
我把central directory 翻译为中央目录, 为什么这么翻译呢?
因为目录区是一块连续的区域(由一系列pk0102区块构成),位于文件的尾部。
但最后的文件尾部由(pk0506)占据
文件前部是一系列pk0304开头+压缩数据+pk0708结尾的区域。
所以可以说目录区算中央。
原来我把它翻译为核心,后来觉得没有”核心”这个意思,由翻译为”中心”,也觉得不妥,
还是觉得中央目录或者中部目录更贴贴吧,或者简单就叫目录,个人之见!
先说说最尾部目录,
这个东西是全局唯一的,位置在尾部,因此特别重要。
结构长度:22 bytes
举例:
0761e70: 6c61 7368 5f68 2e6a 7067 504b 0506 0000 lash_h.jpgPK....
0761e80: 0000 2101 2101 2a54 0000 50ca 7500 0000 ..!.!.*T..P.u...
可见它交代了中央目录的大小和位置,也告诉了你中央目录的个数。
再看看0x75ca50处中央目录数据: 大小0x542a
075ca50: 504b 0102 1400 1400 0800 0800 7965 d344 PK..........ye.D
075ca60: ebde ad91 221f 0000 785b 0000 1400 0000 ...."...x[......
075ca70: 0000 0000 0000 0000 0000 0000 0000 4d45 ..............ME
075ca80: 5441 2d49 4e46 2f4d 414e 4946 4553 542e TA-INF/MANIFEST.
075ca90: 4d46 504b 0102 1400 1400 0800 0800 7965 MFPK..........ye
075caa0: d344 b39e 168c 5421 0000 f15b 0000 1200 .D....T!...[....
075cab0: 0000 0000 0000 0000 0000 0000 641f 0000 ............d...
075cac0: 4d45 5441 2d49 4e46 2f55 4e49 434f 4d2e META-INF/UNICOM.
075cad0: 5346 504b 0102 1400 1400 0800 0800 7965 SFPK..........ye
075cae0: d344 efc7 cd57 ed0b 0000 fe12 0000 1300 .D...W..........
075caf0: 0000 0000 0000 0000 0000 0000 f840 0000 .............@..
075cb00: 4d45 5441 2d49 4e46 2f55 4e49 434f 4d2e META-INF/UNICOM.
075cb10: 5253 4150 4b01 0214 0014 0008 0008 0078 RSAPK..........x
075cb20: 65d3 4444 e759 a3b6 0500 00e0 1300 0013 e.DD.Y..........
075cb30: 0004 0000 0000 0000 0000 0000 0026 4d00 .............&M.
075cb40: 0041 6e64 726f 6964 4d61 6e69 6665 7374 .AndroidManifest
075cb50: 2e78 6d6c feca 0000 504b 0102 1400 1400 .xml....PK......
075cb60: 0800 0800 7865 d344 ........ (忽略)
每个结构长度46bytes,
每一个目录项对应一个文件,记录了压缩,解压的版本,压缩方法。
文件日期,时间,文件名,文件大小,压缩大小,文件偏移地址,crc32等
下一个中央目录记录:
第一个目录提到了,文件头偏移位置为0
第二个目录提到了,文件头偏移位置为0x1f64,
下面分析一下中央目录所指向的数据:
0000000: 504b 0304 1400 0800 0800 7965 d344 0000 PK........ye.D..
0000010: 0000 0000 0000 0000 0000 1400 0000 4d45 ..............ME
0000020: 5441 2d49 4e46 2f4d 414e 4946 4553 542e TA-INF/MANIFEST.
0000030: 4d46 b57c c9ae db58 b2ed bc80 fa87 1cbe MF.|...X........
本地文件头结构: 30bytes
可见本地文件头和目录结构信息是有冗余的。
此时压缩后大小,未压缩大小还是0 在本地扩展头中会填充
.....
0001f50: cffa f7bf 504b 0708 ebde ad91 221f 0000 ....PK......"...
0001f60: 785b 0000 504b 0304 1400 0800 0800 7965 x[..PK........ye
注意:在本地文件尾部我们看到了PK0708,这是本地扩展头,由12byte组成
我们看到一个本地头加上一个扩展本地头可以构成一个中央目录项.
再分析一下第二个文件:
0001f50: cffa f7bf 504b 0708 ebde ad91 221f 0000 ....PK......"...
0001f60: 785b 0000 504b 0304 1400 0800 0800 7965 x[..PK........ye
0001f70: d344 0000 0000 0000 0000 0000 0000 1200 .D..............
0001f80: 0000 4d45 5441 2d49 4e46 2f55 4e49 434f ..META-INF/UNICO
0001f90: 4d2e 5346 957c c7b2 a3d8 b66d ff46 dc7f M.SF.|.....m.F..
本地文件头结构: 30bytes
至此,压缩的数据格式就分析清楚了,至于压缩算法,
如上述9种,实际7种, 就不在本帖之内了。