該工具用python 實現 zipalign 兼容2G以上的apk 包括(64位)
項目地址:
https://github.com/heisai/zipalign
本篇博客 只講解 zip 32, 64的結構.也就是 zipalign 的實現原理:
首先看下zip 的結構吧:
4.3.6 Overall .ZIP file format:
[local file header 1]
[encryption header 1]
[file data 1]
[data descriptor 1]
.
.
.
[local file header n]
[encryption header n]
[file data n]
[data descriptor n]
[archive decryption header]
[archive extra data record]
[central directory header 1]
.
.
.
[central directory header n]
[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 | 擴展區 |
用 010 工具 可以查看 具體字段的 數據, 如下是 Local file header的結構
File data 文件數據
裏面存儲文件的數據,在Local file header 數據段中,filename 之後
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時 也是8 ,[data descriptor] 纔會存在,此時[local file header] 的 crc-32 、compressed size 、uncompressed size 這三個字段都會被儲存爲0,其正確的值會記錄在 [data descriptor] 數據段裏面
Central directory 中心目錄區
Offset | Bytes | Description | 描述 |
---|---|---|---|
0 | 4 | central file header signature | 文件頭標識 |
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 | 文件註釋內容 |
這裏需要注意的是64 位的格式:
1: compressed size 大小大於4個字節 默認寫0xffffffff. 因爲最多隻能存儲四個字節大小.
2: uncompressed size 大小大於4個字節 默認寫0xffffffff. 同上
3: 當文件偏移量 (relative offset of local header) 大於4個字節的時候. 默認寫0xffffffff. 同上
那麼這三個字段的數據真正 存儲在哪呢?
這個三個存儲在 extra field 裏面;
結構如下:
序號 | Value | Size | Description |
---|---|---|---|
1 | (ZIP64) 0x0001 | 2 bytes | Tag for this “extra” block type(zip 64 默認) |
2 | Size | 2 bytes | Size of this “extra” block Original (擴展區的大小,是以上三項數據的大下) |
3 | Size | 8 bytes | Original uncompressed file size Compressed (文件壓縮前的大小) |
4 | Size | 8 bytes | Size of compressed data Relative Header (文件壓縮前的大小) |
5 | Offset | 8 bytes | Offset of local header record Disk Start (文件的偏移量) |
6 | Number | 4 bytes | Number of the disk on which this file starts |
序號1: 固定格式 0x0001 前提是 當 compressed size ,uncompressed size, relative offset of local header 大於四個字節的時候, 這塊數據纔有效.
序號2: 表示擴展區的大小 基本上是8, 16, 24 最後一個四個字節可不寫入
Zip64 end of central directory record 結構
序號 | Description | size |
---|---|---|
1 | zip64 end of central dir signature | 4 bytes (0x06064b50) |
2 | size of zip64 end of central directory record | 8 bytes |
3 | version made by | 2 bytes |
4 | version needed to extract | 2 bytes |
5 | number of this disk | 4 bytes |
6 | number of the disk with the start of the central directory | 4 bytes |
7 | total number of entries in the central directory on this disk | 8 bytes |
8 | total number of entries in the central directory | 8 bytes |
9 | size of the central directory | 8 bytes |
10 | offset of start of central directory with respect to the starting disk number | 8 bytes |
11 | zip64 extensible data sector | (variable size) |
當文件數目 大於65535 的時候. end of central directory record 中心目錄結束記錄 是存放不下的. 所以這個數, 以及中心目錄區的偏移量 都存儲在這裏.
Zip64 end of central directory locator 結構
Description | size |
---|---|
zip64 end of central dir locator signature | 4 bytes (0x07064b50) |
number of the disk with the start of the zip64 end of central directory | 4 bytes |
relative offset of the zip64 end of central directory record | 8 bytes |
total number of disks | 4 bytes |
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 | 中心目錄開始位置相對於.ZIParchive開始的位移 |
20 | 2 | .ZIP file comment length | ZIP文件註釋內容長度(n) |
22 | n | .ZIP file comment | ZIP文件註釋內容 |
主要說下 該磁盤上所記錄的中心目錄數量, 中心目錄開始位置相對於.ZIParchive開始的位移. .
當文件數目小於2個字節 65535 的時候. 那麼獲取文件數就從這裏獲取, 當大於的時候真正獲取文件數目那就的從 Zip64 end of central directory record 結構 中獲取.
中心目錄開始位置相對於.ZIParchive開始的位移 也是.同樣的方式
參考文檔:
[https://thismj.cn/2019/02/14/qian-xi-zip-ge-shi/]
[https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT]