Этот сайт — моя персональная записная книжка. Интересны мне, по большей части, программирование, история и события из моей жизни.

RLE в bzip2

Очень меня поразил тот факт, что внутри очень эффективного архиватора bzip2 работает алгоритм RLE. Да, после очень хитрых перестановок данных, но RLE!

Это очень простое семейство алгоритмов сжатия, с которым я познакомился ещё в то время, когда у меня был «Спектрум».

У него может быть много разных реализаций, но та, что я тогда программировал, выглядела следующим образом.

Последовательности одинаковых значений мы кодируем как один и тот же байт, записанный дважды, плюс счётчик — сколько таких байтов надо дописать; остальное оставляем как есть.

Например:

01 02 03 03 03 03 03 03 03 04 04 04 → 01 02 03 03 05 04 04 01

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

И как-то похожий простой алгоритм трудится внутри bzip2! Мне кажется, этому нельзя не изумиться!

8 комментариев
hsh 5 мес

сколько таких байт надо дописать

байтов?

Евгений Степанищев 5 мес

Ага, спасибо!

Макс 5 мес

Последовательность из двух байт будет сильно оверхедить на один лишний байт. Лучше вариант кодирования битом, после которого количество либо повторений либо количество символов без повторений

Евгений Степанищев 5 мес

Это как, можно пример?

Макс 5 мес

Допустим коды от 00 до 7f кодируют длину последовательности, а 80-ff длину повторений.
02 11 22 33 85 44 раскодируются в 11 22 33 44 44 44 44 44 44
02 кодирует длину равную трем (отчёт с нуля ибо нулевой длины не бывает в данном случае). Аналогично с 85 — кодирует длину 6

Евгений Степанищев 5 мес

Получается ровно та же длина:

02 11 22 33 85 44 ← ваш вариант
11 22 33 44 44 04 ← который я описал

Макс 5 мес

Ну я приводил пример кодирования. А если речь о проблеме, то:
81 11 81 22 против
11 11 00 22 22 00
Если я правильно понял ваш вариант кодирования

Евгений Степанищев 5 мес

Так я и говорю — различные алгоритмы имеют преимущество в разных ситуациях. Закодируйте своим алгоритмом 01 02 03 или 255 кодов FF.

Макс 5 мес

Если говорить о вероятности, то два байта подряд обычно вероятнее чем три. Т. е. скорее всего ваш алгоритм будет менее эффективным, а скорее менее универсальным. Вообще можно провести исследования или просто посмотреть в Википедии реализацию алгоритма в архиваторах. Мне влом. Информацию я достал из своей памяти когда в бородатых 90х дезасемблировал распаковщик. Продолжать спорить нет смысла ибо нам обоим ясны различия и если принципиально, то сами себе найдем доказательства

Евгений Степанищев 5 мес

Так это не мой алгоритм, я его не придумал. Просто один из алгоритмов RLE, коих множество. Этот я тоже писал в 90-х. Любой из них, уверен, может выиграть на своём наборе данных. Спорить действительно особо не о чем.

Evgeny Sureev 5 мес

Я помню как PCX руками распаковывал, чтобы на экране показать. Там был вариант RLE, который Макс описывает.

Евгений Степанищев 5 мес

А это где тебе такое пришлось делать? :)

DSV 2 мес

Если ещё актуально, см. http://drilnet.website
На сайте найдите спойлер RLE кодирование/декодирование своими руками
Попробуйте что-то сжать (например небольшую текстовую строку, только кодировка не UTF-8).
На выходе сжатый файл, плюс 6 байт заголовка.
Реализация на Си и на JavaScript.

Евгений Степанищев 2 мес

Да вроде в RLE никаких особых загадок нет.