Предположим, что простой алгоритм сжатия представляет последовательность a
путем сохранения , то есть некоторый фиксированный заголовок, строка и количество повторений n . Это кодирование по длине прогона . Тогда длина сжатого текста была бы близка к в + Л.Г. п битов для некоторых констант через . , Соответствующий коэффициент сжатия будет + LG ( п )( заголовок , "а" , n )a
N+ Л.Г.Na . Это примерно форма кривой, если смотреть с расстояния, если вы пренебрегаете локальными взлетами и падениями. Асимптотически, степень сжатия составляетΘ(lg(n)p/n)сp≥1(я не сработал, но я подозреваю, что есть другие факторы, которые делают размер выходного суперлинейного по длине строка ввода).+ Л.Г.( н )NΘ ( LG( н )п/ н)р ≥ 1
Л.Г.NNaN+ 1+ 2ana+1na+2n
Поскольку степень сжатия слишком близка к обратной величине длины для визуального наблюдения, в моей реализации приведены данные для небольшой длины (это может зависеть от версии библиотеки bzip2, поскольку существует несколько способов сжатия некоторых входных данных. ). Первый столбец указывает количество a
символов, второй столбец - длину сжатого вывода.
1–3 37
4–99 39
100–115 37
116–258 39
259–354 45
355 43
356 40
357–370 41
371–498 43
499–513 41
514–609 45
610 43
611 41
613–625 42
626–753 44
754–764 42
765 40
766–767 41
768 42
769–864 45
…
Bzip2 намного сложнее , чем простое кодирование длин серий. Он работает в несколько этапов, и первым шагом является этап кодирования по длине прогона , но с фиксированным ограничением размера. Первый шаг работает следующим образом: если байт повторяется по крайней мере 4 раза, то замените байты после 4-го байтом, указывающим количество повторений стертых байтов. Например, aaaaaaa
преобразуется в aaaa\d{3}
(где \d{003}
символ с байтовым значением 3); aaaa
преобразуется в aaaa\d{0}
и т. д. Поскольку имеется только 256 различных байтовых значений, таким образом можно кодировать только последовательности, в которых байт повторяется до 259 раз; если их больше, начинается новая последовательность. Кроме того, эталонная реализация останавливается на счетчике повторов 252, который кодирует строку из 256 байтов.
an1≤n≤34≤n≤258aaaa\d{252}
\d{252}
это число повторений, я не проверял) сам повторяется и, следовательно, сжимается последующими шагами.
aaaa\374aa
n=258a
n=100a101aaaa\d{97}
a
aaaaa
n=101a
A
68≤n≤83
Мой анализ этого примера далеко не исчерпывающий. Чтобы понять другие эффекты, вам нужно изучить другие этапы преобразования: я в основном остановился после шага 1 из 9. Надеюсь, это даст вам представление о том, почему коэффициенты сжатия становятся немного изменчивыми и не изменяются монотонно. Если вы действительно хотите выяснить каждую деталь, я рекомендую взять существующую реализацию и наблюдать за ней с помощью отладчика.
По большей части такие мелкие вариации не являются главной целью при разработке алгоритма сжатия: во многих распространенных сценариях, таких как универсальные алгоритмы или алгоритмы сжатия мультимедиа, разница в несколько байтов не имеет значения. Сжатие пытается выжать каждый бит на локальном уровне и пытается преобразовать цепочки таким образом, чтобы выигрывать часто, редко проигрывая, а затем не сильно. Тем не менее существуют ситуации, например, специальные протоколы связи, предназначенные для связи с низкой пропускной способностью, где важен каждый бит. Другая ситуация, когда точная длина вывода имеет значение, - это когда сжатый текст зашифрован: когда злоумышленник может передать часть текста для сжатия и зашифрования, вариации длины зашифрованного текста могут раскрыть часть сжатого и зашифрованного текста для противник;ПРЕСТУПЛЕНИЕ эксплуатировать на HTTPS .