2009-09-03 18 views
10

Piszę aplikację, która musi rozpakować dane skompresowane przez inną aplikację (co jest poza moją kontrolą - nie mogę wprowadzić zmian w kodzie źródłowym). Aplikacja producenta używa zlib do kompresowania danych przy użyciu mechanizmu z_stream. Często używa Z_FULL_FLUSH (prawdopodobnie zbyt często, moim zdaniem, ale to już inna sprawa). Ta aplikacja innej firmy może również zdekompresować własne dane, więc jestem przekonany, że same dane są poprawne.Upadek dekompresji zlib

W moim teście, używam tej aplikacji firm trzecich do kompresji następujący prosty plik tekstowy (w hex):

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

sprężonego bajtów odbieranych z aplikacji wyglądać tak (ponownie w hex):

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

Gdy próbuję i skompresować te same dane, mam bardzo podobne wyniki:

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

Są dwie różnice, które widzę:

Pierwszy, czwarty bajt jest F2 zamiast F3, więc deflate „końcowy bloku” bit nie został ustawiony. Zakładam, że dzieje się tak dlatego, że interfejs strumienia nigdy nie wie, kiedy będzie koniec danych przychodzących, więc nigdy nie ustawia tego bitu?

Wreszcie, ostatnie cztery bajty w danych zewnętrznych to 00 00 FF FF, podczas gdy w moich danych testowych jest to 24 E9 04 55. Wyszukiwanie wokół znalazłem na tej stronie

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

... że jest to podpis synchronizacji lub pełnego koloru.

Kiedy próbuję dekompresować własne dane za pomocą funkcji decompress(), wszystko działa idealnie. Jednak gdy próbuję zdekompresować dane zewnętrzne, wywołanie funkcji decompress() kończy się niepowodzeniem z kodem powrotu Z_DATA_ERROR, wskazując uszkodzone dane.

mam kilka pytań:

  1. powinienem być w stanie korzystać z zlib „rozpakować” funkcji do dekompresji danych, które zostały skompresowane metodą z_stream?

  2. W powyższym przykładzie, jakie jest znaczenie ostatnich czterech bajtów? Biorąc pod uwagę, że zarówno zewnętrznie skompresowany strumień danych, jak i mój własny strumień danych testowych są tej samej długości, co reprezentują moje ostatnie cztery bajty?

Cheers

+0

Nie mam o tym pojęcia, ale potencjalnie istotne informacje, które zapomniałeś dodać do pytania, to to, jak dokładnie dekompresja zlib kończy się niepowodzeniem. –

+0

Dzięki - dodał też. – Thomi

Odpowiedz

7

Dzięki autorów zlib, znalazłem odpowiedź.Aplikacja osoba trzecia generuje strumienie zlib, które nie są gotowe prawidłowo:

78 9c F2 48 cd C9 C9 57 08 cf 2f ca 49 51 e4 E5 02 00 00 00 ff ff

Jest to częściowy strumień zlib, składający się z nagłówka zlib i częściowego strumienia deflacyjnego . Istnieją dwa bloki , z których żaden nie jest ostatnim blokiem . Drugi blok to pusty blok przechowywany , używany jako znacznik podczas płukania. Dekoder zlib mógłby poprawnie zdekodować to, co tam jest, a następnie dalej szukać danych po tych bajtach po .

78 9c F3 48 cd C9 C9 57 08 CF 2f ca 49 51 E4 E5 02 00 24 E9 04 55

To kompletne strumień zlib składa się z nagłówka zlib, pojedyncze blok oznaczony jako ostatni blok oraz przyczepa zlib . Naczepa jest sumą kontrolną Adler-32 nieskompresowanych danych .

Moja dekompresja zawodzi - prawdopodobnie dlatego, że brakuje CRC lub kod dekompresyjny wciąż szuka więcej danych, które nie istnieją.