Можно ли восстановить поврежденные данные Zlib за пределами поврежденного раздела? - PullRequest
3 голосов
/ 06 апреля 2011

У меня есть Zip-архив с большим (важным) файлом, который не будет извлечен.Все утилиты Zip, которые я пробовал, включая те, которые утверждают, что восстанавливают / исправляют испорченные Zip-архивы, не могут извлечь файл, содержащий поврежденные сжатые данные zlib.Они получают все файлы в архиве за исключением для поврежденной записи, которая пропускается.

Я написал небольшое приложение на C #, которое анализирует zip-архив, идентифицирует каждую запись ианализирует поля, дешифрует разделы данных, а затем распаковывает их, используя DeflateStream (из реализации .Net zlib).Все работает нормально, пока не доберусь до поврежденного входа.Поврежденная запись успешно и полностью расшифровывается (с использованием AES в режиме CTR), но считыватель DeflateStream может пройти через расшифрованные данные только около 40 МБ, прежде чем выдать «Плохое состояние (дерево динамических битов с избыточной подпиской)».

Можно ли каким-то образом «искать» поврежденный раздел и продолжать распаковывать данные?Я хотел бы восстановить как можно большую часть файла, даже если есть некоторые дыры.DeflateStream не реализует метод Seek, и если я пытаюсь создать новый DeflateStream с базовым FileStream, расположенным на последней позиции чтения, он выдает то же исключение «плохое состояние».

1 Ответ

3 голосов
/ 06 апреля 2011

Протокол deflate адаптирует таблицы на основе скользящего окна и прямого потока.

Это не блок - каждый раздел не является отдельной единицей данных, поэтому нет способа просто «пропустить» плохой блок, а есть движущийся «просмотр» потоков, используемых для вычисления / восстановления таблица информации. При этом, мой простой вывод: реально невозможно: (

См. Объяснение протокола "Deflate" .

Восстановление данных меньше, чем раздражительный.


Протокол дефляции фактически имеет «блоки», которые позволяют переключаться между используемым компрессором. Однако я сомневаюсь, что они пригодны для любого вида восстановления. Это очень далеко от MPEG-4, который на самом деле достаточно для восстановления.

Из RFC 1951 , который показывает, насколько это будет сложно:

Обратите внимание, что биты заголовка не обязательно начинаются с границы байта, поскольку блок не обязательно занимает целое число байтов.

И говорить о компрессоре LZ77, способном охватить отдельные блоки: (Это весь поток внутри окна, который используется для построения информации о сжатии).

Обратите внимание, что дублированная ссылка на строку может ссылаться на строку в предыдущем блоке; то есть обратное расстояние может пересекать одну или несколько границ блока.

Однако есть надежда:

Компрессор завершает блок , когда определяет, что было бы полезно начать новый блок со свежими деревьями , или когда размер блока заполняет буфер блока компрессора.

Не луч света, который я бы преследовал: - / Возможно, индивидуальный поиск битов (не все битовые последовательности являются действительными блоками запуска), а затем запуск алгоритма, пока он не потерпел неудачу (предположительно "недействительный" дефлят), затем отступил и попытался снова, пока такой стартовый бит не сгенерирует недопустимые состояния в течение некоторого «приемлемого» периода.

Этот метод потребует модификаций механизма протокола дефляции - это не та задача, которую может обработать обычный процессор потока дефляции.

...