ZIP文件的整體格式 算法
分文件頭信息+文件壓縮數據 函數
中心目錄+中心目錄記錄結束符 編碼
1.分文件頭信息: 加密
字節數 描述 操作系統
4 分文件頭信息標誌(0x04034b50) ci
2 解壓縮所需版本 隨機數
2 通用比特標誌位(置比特0位=加密;置比特1位=使用壓 擴展
縮方式6,並使用8k變化目錄,不然使用4k變化目錄;置比特2位=使用壓 軟件
縮方式6,並使用3個ShannonFano樹對變化目錄輸出編碼,不然使用2個 date
ShannonFano樹對變化目錄輸出編碼,其它比特位未用)
2 壓縮方式(0=不壓縮,1=縮小,2=以壓縮因素1縮小,3=以
壓縮因素2縮小,4=以壓縮因素3縮小,5=以壓縮因素4縮小,6=自展)
2 文件最後修改時間
2 文件最後修改日期
4 32位校驗碼
4 壓縮文件大小
4 未壓縮文件大小
2 文件名長
2 擴展段長
? 文件名(不定長)
? 擴展段(不定長)
2.中心目錄結構
文件頭信息...中心目錄記錄結束符
文件頭:
字節數 描述
4 中心文件頭信息標誌(0x02014b50)
2 主機操做系統(高位字節表示主機操做系統,低位字
節表示ZIP壓縮軟件版本號,其值除以10表示主版本號,其值模10表示
次版本號。0=MS-DOS,OS/2 FAT文件系統,1=Ami ga,2=VMS,3=Unix及
變種,4=VM/CMS,5=AtariST,6=OS/2 HPFS,7=Macintosh,8=Z-System,9
=C P/M,10-255未用)
2 解壓縮所需版本
2 通用比特標誌
2 壓縮方式
2 文件最後修改時間(用標準的MS-DOS時間日 期格式
編碼)
2 文件最後修改日期
4 32位校驗碼(使用David Schwaderer的CRC-32算法產
生)
4 壓縮文件大小
4 未壓縮文件大小
2 文件名長
2 擴展段長
2 文件註釋長(分別爲文件名長,擴展段,註釋 段,小於
64K)
2 磁盤起始號(本文件在磁盤中的起始號)
2 內部文件屬性(最低位若置1,表示爲ASC文本,不然爲
二進制數據,其它位未用)
4 外部文件屬性(依賴於主機操做系統)
4 分文件頭相對位移
? 文件名(不定長)
? 擴展段(不定長,用於將來擴展,低版本爲0長)
? 文件註釋(不定長)
3.中心目錄記錄結束符
字節數 描述
4 中心目錄標記結束符(0x06054b50)
2 磁盤號(其中包括中心目錄結束記錄)
2 磁盤中心目錄起始號
2 磁盤中心目錄入口總數
2 中心目錄入口總數(ZIP文件中的文件總數)
4 整個中心目錄大小
4 關於起始磁盤號的中心目錄初始偏移
2 ZIP文件註釋長度
? ZIP文件註釋(不定長)
加密方法
PKZIP中使用的加密方法由Roger Schlafly提供。ZIP文件在解壓
縮前必須先解密。每一個加密文件具備一個12字節的加密文件頭擴展信
息,存儲於數據區的起始位置,加密前先設置一個起始值,而後被三個3
2位的密鑰加密。密鑰被使用者提供的口令初始化。12個字節加密之
後,由PKZIP的僞隨機數產生方法,結合PKZIP中使用CRC-32算法對密鑰
進行更新。
具體實施分爲三步:
1.用口令對三個32位密鑰初始化。
K(0)=305419896,K(1)=591751049,K(2)=878082192
循環 for i=0 to length(password)-1
調用更新密鑰函數 update_keys(password(i))
結束循環(循環口令長度次)
其中更新密鑰函數爲:
update_keys(char):
Key(0)=crc32(key(0),char)
Key(1)=Key(1)+(Key(0)& 000000ffH)
Key(1)=Key(1)*134775813+1
Key(2)=crc32(Key(2),Key(1)〉〉24)
end update_keys
CRC32函數中,給定一個4字節的CRC值和一個字符,返回一個由CRC
-32算法更新的CRC。具體爲:
crc32(c,b)=crc32tab[(c^b)&0xff]^(c> >8),crc32tab[256]的值
爲固定的256個4字節數。
2.讀取並加密12字節的加密頭,再次對密鑰進行初始化。
將12個字節的加密頭讀入緩衝區buffer(0)至buffer(11),循環fo
r i=0 to 11
C=buffer(i)^decrypt_byte()
update_keys(C)
buffer(i)=C
結束循環(循環12次)
其中的decrypt_byte()函數爲:
unsigned char decrypt_byte()
local unsigned short temp
temp=Key(2)¦2
decrypt_byte=((temp*(temp^1))> > 8)&0xff
end decrypt_byte
該步結束後,緩衝區中最後的二個字節buffer(10)和buffer(11)
將成爲加密文件校驗碼的二個最高位(按低至高順序存放)。對ZIP加
密文件進行解壓縮前,PKUNZIP軟件將使用者提供的口令按上述二個步
驟進行處理,獲得的結果與校驗碼的二個高位字節進行比較,只有當提
供了正確的口令時,結果一致,才能進行後續的解壓縮過程,不然,PKZI
P報告錯誤信息,程序自動結束。
3.讀取壓縮的數據流並以加密密鑰對其進行加密。
壓縮數據流按下述過程加密:
循環 直至數據流結束
C=數據流的一個字節
temp=C^decrypt_byte()
update_keys(temp)
輸出temp
結束循環