2009-09-03 60 views
10

我正在編寫一個應用程序,需要解壓縮由另一個應用程序壓縮的數據(這是我的控制之外 - 我無法更改它的源代碼)。生產者應用程序使用zlib使用z_stream機制壓縮數據。它經常使用Z_FULL_FLUSH(在我看來可能太頻繁了,但那是另一回事)。這個第三方應用程序也能夠解壓它自己的數據,所以我很確信數據本身是正確的。zlib解壓失敗

在我的測試中,我使用這個第三方應用程序來壓縮以下簡單的文本文件(十六進制):

48 65 6c 6c 6f 20 57 6f 72 6c 64 21 0d 0a

我從應用程序接收壓縮字節是這樣的(再次在十六進制):

78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff

如果我嘗試壓縮相同的數據,我得到的結果非常相似:

78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55

有兩個區別,我可以看到:

第一,第四個字節爲F2,而不是F3,所以放氣「最後一塊」位尚未確定。我認爲這是因爲流接口永遠不知道傳入數據的結束時間,所以從不設置該位?

最後,外部數據中的最後四個字節是00 00 FF FF,而在我的測試數據中它是24 E9 04 55。摸索我這個頁面

http://www.bolet.org/~pornin/deflate-flush.html

上發現......這是一個同步或全沖洗的簽名。

當我嘗試使用decompress()函數解壓我自己的數據時,一切正常。但是,當我嘗試解壓外部數據時,decompress()函數調用失敗,返回碼爲Z_DATA_ERROR,表示數據已損壞。

我有幾個問題:

  1. 我應該能夠使用zlib的「解壓縮」功能來解壓縮已壓縮與z_stream方法的數據?

  2. 在上面的例子中,最後四個字節的意義是什麼?考慮到外部壓縮的數據流和我自己的測試數據流的長度相同,我最後四個字節代表什麼?

乾杯

+0

我對此毫無頭緒,但是您忘記添加到您的問題中的潛在相關信息是zlib解壓失敗的原因。 – 2009-09-03 10:38:40

+0

謝謝 - 也補充說。 – Thomi 2009-09-03 10:42:28

回答

7

感謝zlib的作者,我已經找到了答案。第三方應用程序是生成不正確完成的zlib流:

78 9C F2 48 CD C9 C9 57 08 CF 2F CA 49 51 E4 E5 02 00 00 00 FF FF

這是一個部分zlib流, 由zlib標題和一個 部分deflate流組成。有兩個 塊,它們都不是最後的 塊。第二個塊是一個空的 存儲塊,用作 沖洗時的標記。一個zlib解碼器將 正確解碼那裏的內容,然後 繼續在那些字節之後尋找數據 。

78 9C F3 48 CD C9 C9 57 08 CF 2F CA 49 51 E4 E5 02 00 24 E9 04 55

這是一個完整的zlib流, 由ZLIB報頭的,一個單一的 標記爲最後一個塊的塊,以及一個 zlib預告片。預告片是未壓縮的 數據的 Adler-32校驗和。

所以我的解壓失敗 - 可能是因爲CRC丟失,或者解壓縮代碼一直在尋找更多不存在的數據。