2009-09-03 4 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. Searching вокруг я нашел на этой странице

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

... что это подпись синхронизации или полный смыв.

Когда я пытаюсь и распаковываю свои данные с помощью функции decompress(), все работает отлично. Однако при попытке и распаковывании внешних данных вызов функции decompress() завершается с кодом возврата Z_DATA_ERROR, что указывает на поврежденные данные.

У меня есть несколько вопросов:

  1. Должен ли я быть в состоянии использовать ZLIB «распаковывать» функцию распаковывать данные, которые были сжаты с помощью метода z_stream?

  2. В приведенном выше примере, каково значение последних четырех байтов? Учитывая, что как поток сжатого снаружи, так и мой собственный поток тестовых данных имеют одинаковую длину, что представляют собой мои последние четыре байта?

Приветствия

+0

У меня нет ни малейшего понятия об этом, но потенциально соответствующий бит информации, которую вы забыли добавить к вашему вопросу, заключается в том, как именно сбой дефрагментации zlib. –

+0

Спасибо - добавили это тоже. – Thomi

ответ

7

Спасибо авторам ZLIB, я нашел ответ.Приложение третья сторона генерирует ZLib потоки, которые не закончены правильно:

78 9с f2 48 кд с9 с9 57 08 Cf 2f ча 49 51 е4 е5 02 00 00 00 FF FF

Это частичный поток zlib, , состоящий из заголовка zlib и частичного дефлятного потока . Есть два блока , ни один из которых не является последним блоком . Второй блок представляет собой пустой хранимый блок , используемый в качестве маркера при промывке . Декодер zlib будет правильно декодировать то, что там, и , затем продолжить поиск данных после этих байтов.

78 9с f3 48 кд с9 с9 57 08 ср 2f ца 49 51 е4 е5 02 00 24 E9 04 55

То есть полный поток Zlib, , состоящий из заголовка ZLib, один блок, отмеченный как последний блок, и zlib трейлер. Прицеп представляет собой контрольную сумму Adler-32 несжатых .

Так что моя декомпрессия терпит неудачу - возможно, потому, что отсутствует CRC, или код декомпрессии продолжает искать больше данных, которых не существует.

Смежные вопросы