Открыть сервис

LZ77

LZ77 — это алгоритм сжатия данных без потерь, основанный на словарном подходе, в котором повторяющиеся последовательности символов заменяются ссылками на их предыдущие вхождения. Разработан в 1977 году израильскими учёными Авраамом Лемпелем и Якобом Зивом. Относится к классу алгоритмов LZ (Lempel-Ziv), ставших основой для многих современных форматов сжатия, включая DEFLATE, LZMA, LZSS и LZW.

История

Алгоритм LZ77 был впервые описан в статье «A Universal Algorithm for Sequential Data Compression» (IEEE Transactions on Information Theory, 1977). Лемпель и Зив предложили метод, который не требует предварительного построения статистической модели данных, как в алгоритмах Хаффмана или арифметическом кодировании, а работает на лету, анализируя уже обработанный поток.

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

В 1978 году Лемпель и Зив опубликовали модификацию — LZ78, которая использует не скользящее окно, а динамически растущий словарь из всех встреченных фраз. LZ77 остаётся более распространённым в практических реализациях из-за простоты и эффективности.

Принцип работы

Скользящее окно

Алгоритм поддерживает два буфера фиксированного размера:

Размеры этих буферов задаются параметрами алгоритма (например, 4 КБ словарь и 256 байт буфер просмотра). Окно «скользит» по мере обработки: после кодирования фрагмента данные из буфера просмотра перемещаются в словарь, а старые данные «выталкиваются» за пределы окна.

Кодирование

На каждом шаге алгоритм ищет в словаре самую длинную последовательность, совпадающую с началом буфера просмотра. Если совпадение найдено, оно кодируется тройкой чисел:

Если совпадение не найдено (или его длина меньше минимальной), кодируется одиночный символ: смещение и длина равны нулю, а следующий символ — сам этот символ.

Декодирование

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

Пример

Пусть словарь содержит «abcab», а буфер просмотра — «abcde». Алгоритм найдёт совпадение «abc» длиной 3 на смещении 2 (от конца словаря). Он закодирует это как (2, 3, 'd'), где 'd' — первый несовпавший символ. После кодирования окно сдвинется: словарь станет «bcab abc», а буфер — «de...».

Параметры и оптимизации

Размер окна

Чем больше словарь, тем выше вероятность найти длинное совпадение, но тем больше памяти требуется для хранения и поиска. Размер буфера просмотра ограничивает максимальную длину совпадения. Типичные значения: словарь 4–32 КБ, буфер 16–256 байт.

Минимальная длина совпадения

Короткие совпадения (например, 1–2 символа) могут не давать выигрыша, так как тройка занимает больше места, чем исходные символы. Поэтому часто вводят порог (например, 3 символа), ниже которого кодируется одиночный символ.

Поиск совпадений

Наивный поиск (полный перебор словаря) имеет сложность O(n²), что неприемлемо для больших данных. Для ускорения применяются хеш-таблицы, бинарные деревья или алгоритм Ziv-Lempel с хешированием цепочек (LZSS).

Применение

Форматы сжатия

Сети и протоколы

Архиваторы

Преимущества и недостатки

Преимущества

Недостатки

Варианты и модификации

LZSS (1982)

Джеймс Сторер и Томас Шимански предложили модификацию, где:

Этот вариант используется в форматах LHA, ARJ, а также в некоторых реализациях Deflate.

LZ77 с хешированием

Для ускорения поиска совпадений применяется хеш-таблица, где ключом является хеш первых нескольких символов буфера просмотра. Это позволяет находить потенциальные совпадения за O(1) в среднем. Используется в LZMA, zstd, Deflate.

LZ77 с контекстным моделированием

В алгоритмах LZMA и LZMA2 (7-Zip) после поиска совпадений применяется арифметическое кодирование с учётом контекста (например, предыдущих символов, длины совпадения, смещения). Это повышает степень сжатия на 10–30% по сравнению с базовым LZ77.

Интересные факты

Источники

  1. Lempel A., Ziv J. «A Universal Algorithm for Sequential Data Compression». IEEE Transactions on Information Theory, 1977.
  2. Storer J., Szymanski T. «Data Compression via Textual Substitution». Journal of the ACM, 1982.
  3. Salomon D. «Data Compression: The Complete Reference». 4th ed., Springer, 2007.
  4. Sayood K. «Introduction to Data Compression». 5th ed., Morgan Kaufmann, 2017.
  5. RFC 1951 — DEFLATE Compressed Data Format Specification, 1996.
  6. 7-Zip LZMA SDK Documentation, 2022.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →