Формат архивов 7-Zip довольно гибкий и позволяет, например, включать весь архив как один из файлов внутри самого архива, лишь немного считерив. Разберём формат на примере: создадим почти вручную архив с именем «Рекурсивный.7z», содержащий два файла: «Какой-то файл.txt» с содержимым «Hello, Habrahabr!» и «Рекурсивный.7z», копию самого себя.
Краткая документация по формату входит в LZMA SDK. Архив начинается со следующей структуры размером 32 байта. Все позиции внутри архива кодируются как смещения относительно конца этой структуры.
сигнатура, 6 байт: { '7', 'z', 0xBC, 0xAF, 0x27, 0x1C };
версия формата, два байта { Major, Minor }, 7-Zip 9.20 пишет сюда { 0, 3 };
CRC следующих трёх полей, 4 байта;
смещение основного заголовка относительно конца этой структуры, 8 байт;
размер основного заголовка, 8 байт;
CRC основного заголовка, 4 байта.
Далее следуют данные файлов без какой бы то ни было информации о самих файлах и о границах данных. Основной заголовок, который описывает всё содержимое архива, размещается в конце архива.
Основной заголовок может быть сам по себе упакован (а также зашифрован). Поскольку он содержит структурированные данные (типа имён файлов), коэффициент сжатия достаточно неплохой. Именно для возможности подобного сжатия вся информация о файлах в 7z собрана в одном заголовке и полностью отделена от сжатых данных файлов. Признак упакованности — первый байт основного заголовка: он должен быть равен 1 у неупакованного заголовка и 0x17 у упакованного. Для создания архива вручную мы не будем ничего сжимать.
Читать полностью »