10

別のアプリケーションによって圧縮されたデータを解凍する必要があるアプリケーションを作成しています(これは私の制御の範囲外です-そのソースコードに変更を加えることはできません)。プロデューサーアプリケーションは、zlibを使用して、z_streamメカニズムを使用してデータを圧縮します。Z_FULL_FLUSHを頻繁に使用します(私の意見では、おそらくあまりにも頻繁ですが、それは別の問題です)。このサードパーティのアプリケーションは、それ自体のデータを解凍することもできるので、データ自体が正しいと確信しています。

私のテストでは、このサードパーティのアプリを使用して、次の単純なテキストファイル(16進数)を圧縮しています。

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

アプリから受け取る圧縮バイトは次のようになります(これも16進数です)。

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

私が見ることができる2つの違いがあります:

まず、4番目のバイトはF2ではなく。でF3あるため、deflateの「finalblock」ビットは設定されていません。これは、ストリームインターフェイスが着信データの終わりがいつになるかを知らないためだと思います。そのため、そのビットを設定することはありませんか?

最後に、外部データの最後の4バイトはですが00 00 FF FF、私のテストデータでは24 E9 04 55です。このページで見つけた周りを検索

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

...これは同期またはフルフラッシュの署名です。

この関数を使用して自分のデータを解凍しようとするとdecompress()、すべてが完全に機能します。ただし、外部データを解凍しようとすると、decompress()関数呼び出しが失敗し、Z_DATA_ERRORデータが破損していることを示すリターンコードが返されます。

少し質問があります:

  1. zlibの「uncompress」関数を使用して、z_streamメソッドで圧縮されたデータを解凍できるようにする必要がありますか?

  2. 上記の例では、最後の4バイトの意味は何ですか?外部で圧縮されたデータストリームと私自身のテストデータストリームの両方が同じ長さであるとすると、最後の4バイトは何を表しますか?

乾杯

4

2 に答える 2

8

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ヘッダーと部分的なdeflateストリームで構成される部分的なzlibストリームです。2つのブロックがあり、どちらも最後のブロックではありません。2番目のブロックは空の保存ブロックであり、フラッシュ時にマーカーとして使用されます。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が欠落しているか、解凍コードが存在しないデータをさらに探し続けているためです。

于 2009-09-06T09:47:06.377 に答える
3

解決策はここにあります:http: //technology.amis.nl/2010/03/13/utl_compress-gzip-and-zlib/

これは、78個の9C署名圧縮データベースblob(またはストリーム)で開始するための解凍および圧縮関数です。

于 2013-11-15T07:13:38.953 に答える