В современном мире обмен данными‚ резервное копирование и распределение программного обеспечения почти невозможно без файловых архивов. Архив – это контейнер‚ в котором несколько файлов (и иногда папок) упакованы в один единый файл с целью экономии места‚ упрощения передачи и обеспечения целостности данных.
Что такое файловый архив?
Файловый архив – это структурированный набор данных‚ в котором хранится информация о каждом вложенном файле: его имя‚ путь‚ размер‚ временные метки‚ атрибуты и‚ конечно‚ сжатые (или несжатые) данные.
Основные задачи архивов:
- Уменьшение объёма данных за счёт сжатия;
- Объединение нескольких файлов в один контейнер;
- Сохранение и передача метаданных (права доступа‚ даты создания и т.д.);
- Обеспечение целостности (контрольные суммы‚ CRC‚ хеши).
Популярные форматы архивов
Существует множество форматов‚ каждый из которых имеет свои особенности структуры и способы адресации файлов.
| Формат | Расширение | Алгоритмы сжатия | Поддержка больших файлов | Особенности адресации |
|---|---|---|---|---|
| ZIP | .zip | Deflate‚ BZIP2‚ LZMA‚ PPMd | Да (до 4 ГБ в оригинальном стандарте‚ >4 ГБ в ZIP64) | Таблица центрального каталога (Central Directory) в конце файла хранит пути‚ размеры и смещения. |
| RAR | .rar | Rar5‚ LZMA‚ LZMA2 | Да (до 8 ЭБ) | Список блоков (block headers) с относительными смещениями от начала архива. |
| 7z | .7z | LZMA‚ LZMA2‚ PPMd‚ BZIP2‚ Deflate | Да (до 16 ЭБ) | Секция FilesInfo в заголовке хранит полные пути и смещения. |
| TAR | .tar | Без сжатия (обычно комбинируется с gzip‚ bzip2‚ xz) | Да (ограничение 8 ГБ в старом формате‚ >8 ГБ в POSIX‑tar) | Последовательные заголовки 512‑байтовых блоков‚ каждый содержит путь и размер. |
Как внутри архива адресуется каждый файл?
3.1 Общие принципы
Любой архив хранит метаданные о вложенных файлах. Основные поля‚ которые позволяют «найти» файл внутри архива:
- Путь (address) – относительный путь от корня архива (например‚
docs/report.pdf). - Смещение (offset) – позиция в байтах от начала архива до начала сжатых данных файла.
- Размер (compressed / uncompressed) – сколько байт занимает файл в архиве и в оригинальном виде.
- Контрольные суммы – CRC‑32‚ SHA‑1 и т.п.‚ используемые для проверки целостности.
3.2 Пример: ZIP‑архив
- В начале архива находятся локальные заголовки (
Local File Header) каждого файла. В них указаны имя файла и смещение до его данных. - После всех файлов следует центральный каталог (
Central Directory). Он содержит полные записи о каждом файле‚ включая абсолютное смещение (relative offset of local header). - Последняя запись – конец центрального каталога (
End of Central Directory Record)‚ где хранится указатель на начало каталога.
Таким образом‚ чтобы получить доступ к файлу images/logo.png‚ программа читает конец архива‚ находит запись в центральном каталоге‚ получает смещение до локального заголовка и уже оттуда читает сжатые данные.
3.3 Пример: TAR‑архив
В TAR‑архиве каждый файл описывается 512‑байтовым заголовком‚ сразу за которым идут его данные (возможно‚ выровненные до 512‑байтовой границы). Адрес файла – это просто позиция заголовка в потоке. Нет отдельного индекса‚ поэтому для поиска требуется последовательный проход по архиву.
Как работать с адресами файлов программно?
4.1 На уровне командной строки
unzip -l archive.zip– выводит список файлов с их путями и размерами.tar -tvf archive.tar– аналогичный вывод для TAR.7z l archive.7z– список файлов в 7z‑архиве.
4.2 На уровне кода (пример на Python)
import zipfile
with zipfile.ZipFile('example.zip'‚ 'r') as z:
for info in z.infolist:
print(f'Путь: {info.filename}')
print(f'Размер (исходный): {info.file_size} байт')
print(f'Размер (сжатый): {info.compress_size} байт')
print(f'Смещение в архиве: {info.header_offset} байт')
print('-' * 40)
Объект ZipInfo содержит поле header_offset‚ которое указывает на позицию локального заголовка – фактический «адрес» файла внутри архива.
4.3 Принцип «потокового» доступа
Для больших архивов часто используют потоковое чтение без полной распаковки:
- Библиотеки
libarchive‚SharpCompressпозволяют читать отдельные файлы по их пути. - В некоторых форматах (например‚ RAR) поддерживается solid compression – файлы сжаты в один поток‚ и доступ к отдельному файлу требует распаковки всех предшествующих.
Лучшие практики при работе с архивами
- Явно указывайте пути. Не используйте абсолютные пути (например‚
C: empile.txt) – они могут стать уязвимостью (zip‑slip). - Проверяйте контрольные суммы. После распаковки сравнивайте CRC‑32 или SHA‑256 с тем‚ что хранится в архиве.
- Используйте современные форматы (ZIP64‚ 7z‚ RAR5) для поддержки файлов более 4 ГБ.
- Не храните чувствительные данные без шифрования. Форматы вроде 7z поддерживают AES‑256.
- Соблюдайте совместимость. Если архив будет использоваться в разных ОС‚ избегайте символов‚ не поддерживаемых в именах файлов (например‚ «:»‚ «*»).
Часто задаваемые вопросы
6.1 Как узнать‚ какой формат у неизвестного архива?
Большинство форматов имеют «магические числа» в начале файла:
- ZIP –
50 4B 03 04 - RAR –
52 61 72 21 1A 07 00(RAR 4) или52 61 72 5A 58 00(RAR 5) - 7z –
37 7A BC AF 27 1C - TAR – нет уникального сигнатурного кода‚ но часто встречаются блоки 512‑байтовых заголовков.
6.2 Что такое «solid archive» и как это влияет на адресацию?
В solid‑архиве несколько файлов сжаты в один общий поток. Это повышает степень сжатия‚ но делает невозможным прямой доступ к отдельному файлу без декодирования всех предшествующих. В таком случае «адрес» файла – это позиция внутри потока‚ а не отдельный смещение.
6.3 Как защититься от уязвимости Zip Slip?
При извлечении проверяйте‚ что путь файла не выходит за пределы целевой директории:
import os‚ zipfile
def safe_extract(zip_path‚ dest_dir):
with zipfile.ZipFile(zip_path) as z:
for member in z.infolist:
member_path = os.path.abspath(os.path.join(dest_dir‚ member.filename))
if not member_path.startswith(os.path.abspath(dest_dir)):
raise Exception('Attempted Path Traversal Attack')
z.extract(member‚ dest_dir)
Файловые архивы – это не просто «упакованные» файлы‚ а сложные структуры‚ в которых каждый вложенный объект имеет свой адрес (путь + смещение) и набор метаданных. Понимание внутренней организации форматов (ZIP‚ RAR‚ 7z‚ TAR) позволяет эффективно работать с большими наборами данных‚ писать собственные инструменты и обеспечивать безопасность при работе с внешними архивами.
Помните‚ что правильное использование адресов файлов внутри архива – залог надёжного и быстрого доступа к данным.