浅析ZIP格式

ZIP文件格式是一种数据压缩和文档储存的文件格式,原名Deflate,发明者为菲尔·卡茨(Phil Katz),他于1989年1月公布了该格式的资料。ZIP通常使用后缀名“.zip”,它的MIME格式为application/zip。

前言

为什么要了解ZIP格式?因为apk格式实际上也遵循ZIP标准,如果要研究apk打包、签名等流程,那么最好先对ZIP格式有个简单的了解。

分析

一个ZIP压缩文件的通用格式如下:

Overall .ZIP file format:

    [local file header 1]
    [file data 1]
    [data descriptor 1]
    . 
    .
    .
    [local file header n]
    [file data n]
    [data descriptor n]
    [archive decryption header] (EFS)
    [archive extra data record] (EFS)
    [central directory]
    [zip64 end of central directory record]
    [zip64 end of central directory locator] 
    [end of central directory record]

对其中主要的数据段分析如下:

Local file header 文件头

Offset Bytes Description 描述
0 4 local file header signature 文件头标识 (固定值0x04034b50)
4 2 version needed to extract 解压时遵循ZIP规范的最低版本
6 2 general purpose bit flag 通用标志位
8 2 compression method 压缩方式
10 2 last mod file time 最后修改时间(MS-DOS格式)
12 2 last mod file date 最后修改日期(MS-DOS格式)
14 4 crc-32 冗余校验码
18 4 compressed size 压缩后的大小
22 4 uncompressed size 未压缩之前的大小
26 2 file name length 文件名长度(n)
28 2 extra field length 扩展区长度(m)
30 n file name 文件名
30+n m extra field 扩展区


File data 文件数据

储存在[Local file header] 数据段后,用来记录文件本身的数据。

Data descriptor 数据描述

Offset Bytes Description
0 4 数据描述符标识(固定值0x08074b50,ZIP标准里面没有这个字段)
4 4 crc-32 冗余校验码
8 4 compressed size 压缩后的大小
12 4 uncompressed size 未压缩之前的大小

只有当 [local file header] 的 general purpose bit flag 字段第3位Bit置1时,[data descriptor] 才会存在,此时[local file header] 的 crc-32compressed sizeuncompressed size 这三个字段都会被储存为0,其正确的值会记录在 [data descriptor] 数据段里面。

Central directory

根据上面的分析可知,ZIP中的每一个文件,都对应着 [local file header] + [file data] + [data descriptor],而 [central directory] 就是ZIP中所有文件的目录,其储存格式展开如下:

[file header 1]
      .
      .
      . 
[file header n]
[digital signature] 

File header

Offset Bytes Description 描述
0 4 central file header signature 文件头标识 (固定值0x02014b50)
4 2 version made by 高位字节表示文件属性信息的兼容性,
低位字节表示压缩软件支持的ZIP规范版本
6 2 version needed to extract 解压时遵循ZIP规范的最低版本
8 2 general purpose bit flag 通用标志位
10 2 compression method 压缩方式
12 2 last mod file time 最后修改时间(MS-DOS格式)
14 2 last mod file date 最后修改日期(MS-DOS格式)
16 4 crc-32 冗余校验码
20 4 compressed size 压缩后的大小
24 4 uncompressed size 未压缩之前的大小
28 2 file name length 文件名长度(n)
30 2 extra field length 扩展区长度(m)
32 2 file comment length 文件注释长度(k)
34 2 disk number start 文件开始位置的磁盘编号
36 2 internal file attributes 内部文件属性
38 4 external file attributes 外部文件属性
42 4 relative offset of local header 对应 [local file header] 的偏移位置
46 n file name 目录文件名
46+n m extra field 扩展域
46+n+m k file comment 文件注释内容


digital signature

Offset Bytes Description 描述
0 4 header signature 数字签名头标识 (固定值0x05054b50)
4 2 size of data 数字签名数据大小(n)
6 n signature data 数字签名数据


end of central directory record 中心目录结束记录

Offset Bytes Description 描述
0 4 end of central dir signature 中心目录结束标识 (固定值0x06054b50)
4 2 number of this disk 当前磁盘编号
6 2 number of the disk with the
start of the central directory
中心目录开始位置的磁盘编号
8 2 total number of entries in the
central directory on this disk
中心目录开始位置的磁盘编号
10 2 total number of entries in
the central directory
该磁盘上所记录的中心目录数量
12 4 size of the central directory 中心目录大小
16 4 offset of start of central
directory with respect to
the starting disk number
中心目录开始位置相对于.ZIP archive开始的位移
20 2 .ZIP file comment length ZIP文件注释内容长度(n)
22 n .ZIP file comment ZIP文件注释内容



根据以上的分析,可以知道一个ZIP压缩文件,主要包含三个部分,即:

Alt text

实验

我们在Mac OS下打包一个ZIP文件,来与上面的分析做一个对比,文件目录如下所示:

.
├── a.txt
└── b
    └── c.txt

1 directory, 2 files

用Sublime打开ZIP压缩文件:

504b 0304 1400 0800 0800 0588 4d4e 0000 
0000 0000 0000 0000 0000 0500 1000 612e
7478 7455 580c 009b dc63 5c9a dc63 5c57
3c14 002b c9c8 2c56 00a2 b4a2 fc5c 8544
3d00 504b 0708 3098 2c41 0f00 0000 0f00
0000 504b 0304 0a00 0000 0000 0d88 4d4e
0000 0000 0000 0000 0000 0000 0900 1000
5f5f 4d41 434f 5358 2f55 580c 00aa dc63
5caa dc63 5c57 3cec 8250 4b03 0414 0008
0008 0005 884d 4e00 0000 0000 0000 0000
0000 0010 0010 005f 5f4d 4143 4f53 582f
2e5f 612e 7478 7455 580c 009b dc63 5c9a
dc63 5c57 3c14 0063 6015 6367 6062 60f0
4d4c 56f0 0f56 8850 8002 9018 0327 101b
3130 30c6 0169 209f 7102 0351 c031 2424
08c2 02e9 60e4 0032 3ad0 9430 43c5 f919
18c4 93f3 73f5 120b 0a72 52f5 4252 2b4a
5cf3 92f3 5332 f3d2 21fa c581 8400 0383
1442 4d4e 6271 4969 716a 4a4a 6249 aa72
4030 d41e 7520 91c9 c060 8e50 979b 5a92
0854 9368 95ed ebe2 9398 949a 135f 5c92
959d 9897 9f98 9596 9d93 9392 9666 9e51
5a54 9169 6e52 5609 d45c 5a92 a66b 616d
686c 6264 686e 6961 d27d 2739 0664 b0f4
a373 6220 fa93 5d43 c3cb 53a6 4b57 702e
daaa a4bf d8c3 2453 3022 7fff 8cf3 2d47
1c0f 9d12 3a97 f329 b63a ffdc 875b 933b
ceed 5256 9467 555c 7791 31fb e331 8d48
21e9 4bde fd11 f24e 6fa2 ea53 7ce5 19ff
e8f1 9e62 292b e44a 955a ef79 8edd e74c
eb96 6379 22ca e993 19ca be04 28a8 856e
6bb8 0300 504b 0708 3695 1560 2d01 0000
9001 0000 504b 0304 0a00 0000 0000 0a88
4d4e 0000 0000 0000 0000 0000 0000 0200
1000 622f 5558 0c00 aadc 635c a3dc 635c
573c 1400 504b 0304 1400 0800 0800 0a88
4d4e 0000 0000 0000 0000 0000 0000 0700
1000 622f 632e 7478 7455 580c 00a8 dc63
5ca3 dc63 5c57 3c14 002b c9c8 2c56 00a2
b4a2 fc5c 8564 3d00 504b 0708 b2fa 1a73
0f00 0000 0f00 0000 504b 0304 0a00 0000
0000 0d88 4d4e 0000 0000 0000 0000 0000
0000 0b00 1000 5f5f 4d41 434f 5358 2f62
2f55 580c 00aa dc63 5caa dc63 5c57 3cec
8250 4b03 0414 0008 0008 000a 884d 4e00
0000 0000 0000 0000 0000 0012 0010 005f
5f4d 4143 4f53 582f 622f 2e5f 632e 7478
7455 580c 00a8 dc63 5ca3 dc63 5c57 3c14
0063 6015 6367 6062 60f0 4d4c 56f0 0f56
8850 8002 9018 0327 101b 01f1 4620 06f1
1f33 1005 1c43 4282 a04c 908e 2340 2c8f
a684 092a cecf c020 9e9c 9fab 9758 5090
93aa 1792 5a51 e29a 979c 9f92 9997 0e51
7719 8805 1818 a410 6a72 128b 4b4a 8b53
5352 124b 5295 0382 418a 4a4b d274 2dac
0d8d 4d8c 0ccd 2d2d 4ce6 dd49 8e01 0957
7b69 aa82 6800 504b 0708 7d78 286a 8500
0000 e300 0000 504b 0102 1503 1400 0800
0800 0588 4d4e 3098 2c41 0f00 0000 0f00
0000 0500 0c00 0000 0000 0000 0040 a481
0000 0000 612e 7478 7455 5808 009b dc63
5c9a dc63 5c50 4b01 0215 030a 0000 0000
000d 884d 4e00 0000 0000 0000 0000 0000
0009 000c 0000 0000 0000 0000 40fd 4152
0000 005f 5f4d 4143 4f53 582f 5558 0800
aadc 635c aadc 635c 504b 0102 1503 1400
0800 0800 0588 4d4e 3695 1560 2d01 0000
9001 0000 1000 0c00 0000 0000 0000 0040
a481 8900 0000 5f5f 4d41 434f 5358 2f2e
5f61 2e74 7874 5558 0800 9bdc 635c 9adc
635c 504b 0102 1503 0a00 0000 0000 0a88
4d4e 0000 0000 0000 0000 0000 0000 0200
0c00 0000 0000 0000 0040 ed41 0402 0000
622f 5558 0800 aadc 635c a3dc 635c 504b
0102 1503 1400 0800 0800 0a88 4d4e b2fa
1a73 0f00 0000 0f00 0000 0700 0c00 0000
0000 0000 0040 a481 3402 0000 622f 632e
7478 7455 5808 00a8 dc63 5ca3 dc63 5c50
4b01 0215 030a 0000 0000 000d 884d 4e00
0000 0000 0000 0000 0000 000b 000c 0000
0000 0000 0000 40fd 4188 0200 005f 5f4d
4143 4f53 582f 622f 5558 0800 aadc 635c
aadc 635c 504b 0102 1503 1400 0800 0800
0a88 4d4e 7d78 286a 8500 0000 e300 0000
1200 0c00 0000 0000 0000 0040 a481 c102
0000 5f5f 4d41 434f 5358 2f62 2f2e 5f63
2e74 7874 5558 0800 a8dc 635c a3dc 635c
504b 0506 0000 0000 0700 0700 da01 0000
9603 0000 0000 

Mac下的ZIP文件存储采用的是utf-8编码,我们根据ZIP文件的结构进行对照解析,通过固定值标识以及偏移找到对应字段的数据值,非内容字段值存储采用的是小端字节序,下面表格列出的值都已转换成了我们能阅读的大端字节序,源文件数据储存区解析(部分字段)如下表:

字段 解析
local file header signature 0x04034b50 固定值
version needed to extract 0x0014 20/10=2 20%10=0 最低ZIP规范版本为2.0
general purpose bit flag 0x0008 0000 0000 0000 1000(第3位Bit为1)
file name length 0x0005 文件名长度为 5 Bytes
file name 0x612e747874 a.txt

字段 解析
local file header signature 0x04034b50 固定值
file name length 0x0009 文件名长度为 9 Bytes
file name 0x5f5f4d41434f53582f __MACOSX/

字段 解析
local file header signature 0x04034b50 固定值
file name length 0x0010 文件名长度为 9 Bytes
file name 0x5f5f4d41434f53582f2e __MACOSX/.

字段 解析
local file header signature 0x04034b50 固定值
file name length 0x0002 文件名长度为 2 Bytes
file name 0x622f b/

字段 解析
local file header signature 0x04034b50 固定值
file name length 0x0007 文件名长度为 7 Bytes
file name 0x622f632e747874 b/c.txt

字段 解析
local file header signature 0x04034b50 固定值
file name length 0x000b 文件名长度为 11 Bytes
file name 0x5f5f4d41434f53582f622f __MACOSX/b/

……(还有文件,不看了,眼睛都看花了,一大堆Mac文件系统的隐藏文件也打进ZIP了)

中心目录区跟中心目录结束标识区也可以按照相同的方法进行手动解析,在此就不一一验证了。

总结

由此,也算了解了ZIP压缩文件的基本格式,还有些问题需要探究,在此记录一下,后续有需求的话再来钻研。

  1. ZIP格式的中心目录区的意义? 能想到的有两点,一是因为中心目录区的存在,可以在不解压文件的情况下快速列出ZIP的目录;二是中心目录区文件头的偏移值能够快速定位到对应的源文件储存区的位置。
  2. ZIP的压缩方式?加密方式?
  3. 源文件储存区的数据是如何保证完整性的,也就是数据进行数字签名的方式等等。
  4. [archive decryption header]、[archive extra data record]等。

参考文章


  转载请注明: ThisMJ 浅析ZIP格式

 上一篇
AAPT命令行使用实践 AAPT命令行使用实践
环境 操作系统:Mac OS High Sierra 10.13.2 (17C88) Android SDK Build Tool版本:28.0.3 AAPT是什么AAPT 即 Android Asset Packaging Tool,它
2019-03-06
下一篇 
2019年初,给30岁之际的自己立些儿Flag 2019年初,给30岁之际的自己立些儿Flag
写在前头的话一直都没有做过总结,自我认知也是比较主观,所以有的时候会比较茫然,不知道怎么去弥补自己的不足,让自己成为一个优秀的人。回想一下,毕业快四年半了,没什么值得自己骄傲的事情,反而是磨灭了年轻时的热情。因为没有一个系统的规划,抬起脚都
2019-01-14
  目录