Что такое код gzcompress


gzcompress

gzcompress — сжимает строку.

Описание

string gzcompress (string data [, int level])

Эта функция возвращает сжатую версию входных данных data, используя формат данных ZLIB, или FALSE, если обнаружена ошибка. Необязательный параметр level может быть задан от 0 — нет сжатия, до 9 — максимальное сжатие.

Примечание: это не то же самое, что gzip-компрессия, которая включает некоторые header-данные. См. в gzencode() о gzip-компрессии.

Сжатие строки в zlib-формате (RFC1950) (ищу аналог функции php — gzcompress)

Всем привет! Нужно для одного веб-сервиса перед отправкой параметров зашифровать строку JSON по следующему алгоритму (цитирую, как написано в документации):

«JSON структура чека должна быть сжата алгоритмом DEFLATE, описанным в RFC1951, а после представлена в ZLIB формате, описанным в RFC1950. Далее результат кодируется в BASE64 и передается в параметре cheque.»

У самих разработчиков веб-сервиса JSON строка шифруется с помощью строки в php:
$cheque = base64_encode(gzcompress($cheque_json));

Нужен аналог такой функции на C#. Помогите. Пробую разные функции и алгоритмы, зашифрованная строка отличается от той, что нужна веб-сервису (есть примеры того, что было, и во что закодировалось).

Добавлено через 2 часа 22 минуты
Как часто и бывает, ответа не дождалась. Но оставлю информацию тем, кто столкнется.
Итак, для кодирования данных помог такой класс:

How to forb > Ask Question

When I use the riscv64-unknown-elf-gcc, there is few differences between option -march=rv64g and -march=rv64gc .

-march=64g will use RVC codes in standard library functions, for example, the prinft, as much as possible but not in my own functions. While the -march=64gc , use the RVC codes in both types of functions.

I don’t know whether this is default. But if I want to forbid the RVC codes so that even in the standard library functions without the RVC codes, what should I do?

gzcompress Php в Java

Я пытаюсь сжать строку в Java, как функция gzcompress РНР это делает. Но я не могу получить те же массивы байт в результате.

Мой код PHP:

Результат:

Java-код:

Результат:

Входной сигнал: Это тест

Средние части сжатых массивов одинаковы. Но они отличаются в начале и в конце.

Документация для функции gzcompress конкретно говорится , что алгоритм сжатия использует это Zlib, который

не то же самое, как сжатие GZIP, который включает в себя некоторые данные заголовка. См gzencode () для сжатия GZIP.

GZIPOutputStream в Java делает правильное сжатие GZIP , включая правильные заголовки. DeflaterOutputStream делает обычный выкачать без GZIP заголовков, которые могут быть ближе к тому , что вы после этого , или есть решения сторонних такие как JZlib .

Его утверждает, что начало файла должно содержать.

CM (Метод сжатия) Это определяет метод сжатия, используемый в файле. CM = 0-7 зарезервированы. СМ = 8 обозначает метод сжатия «выкачать», которая является одним, обычно используемыми Gz и который документированный в другом месте.

Таким образом, первые три байта должно быть 31, 139, 8. Четвертый байт должен быть значение между 0-31 (с использованием битов 0 до 4, и 5,6, и 7 зарезервированы). Я подозреваю, что выход вы видите в PHP не GZ формат.

JavaScript компрессоры и зачем они нужны

Что такое минимизация

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

Минимизация объёма кода ведёт к уменьшению размера файла, а это значит, что он быстрее будет загружаться и исполняться. В формате небольшой программы выгода ничтожна, но в больших проектах с подключением библиотек, вроде jQuery, это позволит увеличить производительность в разы.

Как это выглядит

Трудно оценить, как это работает, без примера. Вот так выглядит оригинальный код:

window.onload = function() <
// setup the button click
document.getElementBy > doWork()
>;
>

function doWork() <
// ajax the JSON to the server
$.post(«receiver», cars, function()<

>);
// stop link reloading the page
event.preventDefault();
>

А вот так он выглядит после минимизации:

В результате объём кода уменьшился на 39%. При этом компрессии удалось добиться только за счёт сокращения числа пробелов и удаления комментариев, имена переменных были сохранены.

Если распространить этот алгоритм на популярные JS-библиотеки, их объём изменится следующим образом:

  • JQuery: до минимизации 270 KB, после 90 KB.
  • Highcharts: до минимизации 1 MB, после 201 KB.
  • MooTools: до минимизации 164 KB, после 93 KB

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

Как это работает

Теперь, когда вы убедились в эффективности минимизации, давайте рассмотрим, как это делается. Главное правило – не вздумайте делать минимимзацию вручную, это приведёт лишь к появлению ошибок. За вас все сделают специальные инструменты, способные применять различные алгоритмы к вашему коду.

Наиболее популярное решение — онлайн-сервис. Единственное существенное отличие между ними – работа непосредственно с кодом или файлом. В любом случае, весь процесс для вас займёт не более 5 кликов. Вот несколько:

  • JSCompress – простой быстрый сайт. Большой плюс – возможность посмотреть на инструменты, которые использовались для его создания.
  • DansTools JavaScript Minifier – сервис, позволяющий интегрировать его в свой веб-сайт.
  • JavaScript Minifier — здесь нет ничего, кроме компрессора и одной кнопки.
  • Minify — Полная противоположность предыдущему компрессору. Великолепный сайт, заслуживающий внимания.

Количество сервисов огромно, перечислять все бесполезно. Выбирайте тот, что ближе вашему образу мышления и милее глазу.

Другое решение – использование встроенных инструментов в IDE или редакторы. По понятным причинам они намного быстрее, не требуют копипаста и разделения кода на языки и фрагменты.

Так, например, в Microsoft Visual Studio существует расширение Bundler & Minifier. На данный момент его скачало почти 400 тысяч человек. Также оно доступно на GitHub и постоянно развивается.

Поклонникам Sublime Text следует скачать пакет Minify. У него более 61 000 скачиваний и он также доступен на GitHub.

Наконец, для пользователей PyCharm популярным решением является компрессор YUI. В общем, практически любой популярный продукт имеет плагин для минимизации кода.

Обратная сторона медали

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

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

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

Что такое минимизация

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

Минимизация объёма кода ведёт к уменьшению размера файла, а это значит, что он быстрее будет загружаться и исполняться. В формате небольшой программы выгода ничтожна, но в больших проектах с подключением библиотек, вроде jQuery, это позволит увеличить производительность в разы.

Как это выглядит

Трудно оценить, как это работает, без примера. Вот так выглядит оригинальный код:

window.onload = function() <
// setup the button click
document.getElementBy > doWork()
>;
>

function doWork() <
// ajax the JSON to the server
$.post(«receiver», cars, function()<

>);
// stop link reloading the page
event.preventDefault();
>

А вот так он выглядит после минимизации:

В результате объём кода уменьшился на 39%. При этом компрессии удалось добиться только за счёт сокращения числа пробелов и удаления комментариев, имена переменных были сохранены.

Если распространить этот алгоритм на популярные JS-библиотеки, их объём изменится следующим образом:

  • JQuery: до минимизации 270 KB, после 90 KB.
  • Highcharts: до минимизации 1 MB, после 201 KB.
  • MooTools: до минимизации 164 KB, после 93 KB

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

Как это работает

Теперь, когда вы убедились в эффективности минимизации, давайте рассмотрим, как это делается. Главное правило – не вздумайте делать минимимзацию вручную, это приведёт лишь к появлению ошибок. За вас все сделают специальные инструменты, способные применять различные алгоритмы к вашему коду.

Илон Маск рекомендует:  number_format - Форматирует число с разделением групп

Наиболее популярное решение — онлайн-сервис. Единственное существенное отличие между ними – работа непосредственно с кодом или файлом. В любом случае, весь процесс для вас займёт не более 5 кликов. Вот несколько:

  • JSCompress – простой быстрый сайт. Большой плюс – возможность посмотреть на инструменты, которые использовались для его создания.
  • DansTools JavaScript Minifier – сервис, позволяющий интегрировать его в свой веб-сайт.
  • JavaScript Minifier — здесь нет ничего, кроме компрессора и одной кнопки.
  • Minify — Полная противоположность предыдущему компрессору. Великолепный сайт, заслуживающий внимания.

Количество сервисов огромно, перечислять все бесполезно. Выбирайте тот, что ближе вашему образу мышления и милее глазу.

Другое решение – использование встроенных инструментов в IDE или редакторы. По понятным причинам они намного быстрее, не требуют копипаста и разделения кода на языки и фрагменты.

Так, например, в Microsoft Visual Studio существует расширение Bundler & Minifier. На данный момент его скачало почти 400 тысяч человек. Также оно доступно на GitHub и постоянно развивается.

Поклонникам Sublime Text следует скачать пакет Minify. У него более 61 000 скачиваний и он также доступен на GitHub.

Наконец, для пользователей PyCharm популярным решением является компрессор YUI. В общем, практически любой популярный продукт имеет плагин для минимизации кода.

Обратная сторона медали

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

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

Что такое код gzcompress

В окне будет показана следующая строка:

78 9C F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
Часть строки я специально выделил красным цветом, дальше будет понятно зачем это сделано.

А теперь проделаем то же самое, но на PHP. Простенький скрипт покажет результаты работы обеих функций с разными параметрами сжатия. Строка, естественно, та же самая.

  1. $str = «ManHunter» ;
  2. for ( $cl = 0 ; $cl 10 ; $cl ++) <
  3. if ( $cl == 10 ) <
  4. echo «DFLT — » ;
  5. $tmp = gzdeflate ( $str );
  6. >

  7. else <
  8. echo «CL=» . $cl . » — » ;
  9. $tmp = gzdeflate ( $str , $cl );
  10. >
  11. for ( $i = 0 ; $i strlen ( $tmp ); $i ++) <
  12. printf ( «%02X » , ord ( substr ( $tmp , $i , 1 )));
  13. >
  14. echo «
    » ;
  15. >
  16. echo «
    » ;
  17. for ( $cl = 0 ; $cl 10 ; $cl ++) <
  18. if ( $cl == 10 ) <
  19. echo «DFLT — » ;
  20. $tmp = gzcompress ( $str );
  21. >
  22. else <
  23. echo «CL=» . $cl . » — » ;
  24. $tmp = gzcompress ( $str , $cl );
  25. >
  26. for ( $i = 0 ; $i strlen ( $tmp ); $i ++) <
  27. printf ( «%02X » , ord ( substr ( $tmp , $i , 1 )));
  28. >
  29. echo «
    » ;
  30. >
  31. ?>

Результаты работы скрипта:

CL=0 — 01 09 00 F6 FF 4D 61 6E 48 75 6E 74 65 72
CL=1 — F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=2 — F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=3 — F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=4 — F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=5 — F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=6 — F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=7 — F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=8 — F3 4D CC F3 28 CD 2B 49 2D 02 00
CL=9 — F3 4D CC F3 28 CD 2B 49 2D 02 00
DFLT — F3 4D CC F3 28 CD 2B 49 2D 02 00

CL=0 — 78 01 01 09 00 F6 FF 4D 61 6E 48 75 6E 74 65 72 11 11 03 93
CL=1 — 78 01 F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=2 — 78 5E F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=3 — 78 5E F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=4 — 78 5E F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=5 — 78 5E F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=6 — 78 9C F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=7 — 78 DA F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=8 — 78 DA F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
CL=9 — 78 DA F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
DFLT — 78 9C F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
Здесь тоже выделены некоторые строки. Они частично совпадают в случае использования gzdeflate и gzcompress, а в случае gzcompress с дефолтной степенью сжатия строка вообще полностью идентична результатам вызова функции compress библиотеки zlib. Можно сделать первые выводы: результат работы gzdeflate — только упакованные данные, а gzcompress — заголовок + упакованные данные + служебные данные. Возможно, служебные данные — это контрольная сумма или что-то около того, потому что при ее изменении распаковка вылетает с ошибкой. Но упакованные данные, выделенные красным цветом, во всех трех случаях одинаковые. Отсюда следует, что строка, сжатая командой gzcompress, распаковывается функцией uncompress библиотеки zlib без каких-либо изменений, и если в коде PHP-скрипта встречается функция gzuncompress, то ее аргументы можно смело распаковывать штатными средствами. А как быть с gzinflate, если у ее аргументов отсутствуют служебные данные? Попробуем просто дописать их и распаковать полученную строку.

  1. format PE GUI 4 . 0
  2. entry start
  3. include ‘win32a.inc’
  4. section ‘.data’ datareadablewriteable
  5. strr db 078h , 09Ch ; Заголовок
  6. db 0F3h , 04Dh , 0CCh , 0F3h , 028h , 0CDh , 02Bh , 049h , 02Dh , 002h , 000
  7. db 0 , 0 , 0 , 0 ; Служебные данные неизвестны, просто заменим их нулями
  8. lend = $ — strr
  9. bsize = 1000
  10. blen dd bsize
  11. tmp rb bsize
  12. ;———————————————————-
  13. section ‘.code’ codereadableexecutable
  14. start :
  15. invoke uncompress , tmp , blen , strr , dword lend
  16. invoke MessageBox , HWND_DESKTOP , tmp , NULL , MB_OK
  17. invoke ExitProcess , 0
  18. ;———————————————————-
  19. section ‘.idata’ importdatareadablewriteable
  20. library kernel32 , «kernel32.dll» , \
  21. user32 , «user32.dll» , \
  22. zlib , «zlib1.dll»
  23. include «apia\kernel32.inc»
  24. include «apia\user32.inc»
  25. import zlib , \
  26. uncompress , ‘uncompress’

Компилируем, запускаем, опа! Получаем распакованную исходную строку. Отсюда следует, что для распаковки строки, запакованной gzdeflate, к ней в начало достаточно дописать два байта заголовка 078h и 09Ch, а служебную информацию в конец строки можно записывать любую. После этого строка легко распаковывается функцией uncompress библиотеки zlib. Во всех виденных мной протекторах и зашифрованных скриптах, функции упаковки вызываются с дефолтными параметрами, а значит и распаковываются по описанной выше схеме.

В приложении скрипт на PHP и примеры программ на Ассемблере, использованные в статье. Исходники без комментариев, все параметры вызова функций zlib можно посмотреть на офсайте или в прилагаемой к дистрибутиву документации.

Что такое код gzcompress

Mark R. Nelson
Перевод: Запольский С.А.

Собственно исходный Lempel/Ziv подход к сжатию данных был впервые обнародован в 1977г., а усовершенствованный (Terry Welch) вариант был опубликован в 1984г. Алгоритм на удивление прост. Если в двух словах, то LZW-сжатие заменяет строки символов некоторыми кодами. Это делается без какого-либо анализа входного текста. Вместо этого при добавлении каждой новой строки символов просматривается таблица строк. Сжатие происходит, когда код заменяет строку символов. Коды, генерируемые LZW-алгоритмом, могут быть любой длины, но они должны содержать больше бит, чем единичный символ. Первые 256 кодов (когда используются 8-битные символы) по умолчанию соответствуют стандартному набору символов. Остальные коды соответствуют обрабатываемым алгоритмом строкам.

Простая программа, приведенная ниже, работает с 12-битными кодами. Значения кодов 0 — 255 соответствуют отдельным байтам, а коды 256 — 4095 соответствуют подстрокам.


Сжатие.

Алгоритм LZW-сжатия в простейшей форме приведен на рис.1. Каждый раз, когда генерируется новый код, новая строка добавляется в таблицу строк. LZW постоянно проверяет, является ли строка уже известной, и , если так, выводит существующий код без генерации нового.

СТРОКА = очередной символ из входного потока
WHILE входной поток не пуст DO
СИМВОЛ = очередной символ из входного потока
IF СТРОКА+СИМВОЛ в таблице строк THEN
СТРОКА = СТРОКА+СИМВОЛ
ELSE
вывести в выходной поток код для СТРОКА
добавить в таблицу строк СТРОКА+СИМВОЛ
СТРОКА = СИМВОЛ
END of IF
END of WHILE
вывести в выходной поток код для СТРОКА

Илон Маск рекомендует:  Что такое код fbsql_read_blob

Рис. 1 Алгоритм сжатия

Простая строка, использованная для демонстрации алгоритма, приведена на рис.2. Входная строка является кратким списком английских слов, разделенных символом «/». Как вы можете заметить, анализируя алгоритм, его работа начинается с того, что на первом шаге цикла он выполняет проверку на наличие строки «/W» в таблице. Когда он не находит эту строку, то генерирует код для «/» и добавляет в таблицу строку «/W». Т.к. 256 символов уже определены для кодов 0 — 255, то первой определенной строке может быть поставлен в соответствие код 256. После этого система читает следующую букву («E»), добавляет вторую подстроку («WE») в таблицу и выводит код для буквы «W».

Этот процесс повторяется до тех пор, пока вторая подстрока, состоящая из прочитанных символов «/» и «W», не сопоставится со строковым номером 256. В этом случае система выводит код 256 и добавляет трехсимвольную подстроку в таблицу. Этот процесс продолжается до тех пор, пока не исчерпается входной поток и все коды не будут выведены.

Входная строка : /WED/WE/WEE/WEB/WET

Вход(символы) Выход(коды) Новые коды и соответствующие строки
/W / 256 = /W
E W 257 = WE
D E 258 = ED
/ D 259 = D/
WE 256 260 = /WE
/ E 261 = E/
WEE 260 262 = /WEE
/W 261 263 = E/W
EB 257 264 = WEB
/ B 265 = B/
WET 260 266 = /WET
T

Рис. 2 Процесс сжатия

Выходной поток для заданной строки показан на рис. 2, также как и полученная в результате таблица строк. Как вы можете заметить, эта таблица быстро заполняется, т.к. новая строка добавляется в таблицу каждый раз, когда генерируется код. В этом явно вырожденном примере было выведено пять закодированных подстрок и семь символов. Если использовать 9-битные коды для вывода, то 19-символьная входная строка будет преобразована в 13.5-символьная выходную строку. Конечно, этот пример был выбран только для демонстрации. В действительности сжатие обычно не начинается до тех пор, пока не будет построена достаточно большая таблица, обычно после прочтения порядка 100 входных байт.


Распаковка.

Алгоритму сжатия соответствует свой алгоритм распаковки. Он получает выходной поток кодов от алгоритма сжатия и использует его для точного восстановления входного потока. Одной из причин эффективности LZW-алгоритма является то, что он не нуждается в хранении таблицы строк, полученной при сжатии. Таблица может быть точно восстановлена при распаковке на основе выходного потока алгоритма сжатия. Это возможно потому, что алгоритм сжатия выводит СТРОКОВУЮ и СИМВОЛЬНУЮ компоненты кода прежде чем он поместит этот код в выходной поток. Это означает, что сжатые данные не обременены необходимостью тянуть за собой большую таблицу перевода.

Алгоритм распаковки представлен на рис. 3. В соответствии с алгоритмом сжатия, он добавляет новую строку в таблицу строк каждый раз, когда читает из входного потока новый код. Все, что ему необходимо сделать в добавок — это перевести каждый входной код в строку и переслать ее в выходной поток.

читать СТАРЫЙ_КОД
вывести СТАРЫЙ_КОД
WHILE входной поток не пуст DO
читать НОВЫЙ_КОД
СТРОКА = перевести НОВЫЙ_КОД
вывести СТРОКУ
СИМВОЛ = первый символ СТРОКИ
добавить в таблицу перевода СТАРЫЙ_КОД+СИМВОЛ
СТАРЫЙ_КОД = НОВЫЙ_КОД
END of WHILE

Рис. 3 Алгоритм распаковки

На рис. 4 приведена схема работы алгоритма на основе сжатых данных, полученных в выше приведенном примере. Важно отметить, что построение таблицы строк алгоритмом распаковки заканчивается как раз тогда, когда построена таблица строк алгоритма сжатия.

Входные коды : / W E D 256 E 260 261 257 B 260 T

Вход СТАРЫЙ КОД СТРОКА СИМВОЛ Новый вход таблицы
/ / /
W / W W 256 = /W
E W E E 257 = WE
D E D D 258 = ED
256 D /W / 259 = D/
E 256 E E 260 = /WE
260 E /WE / 261 = E/
261 260 E/ E 262 = /WEE
257 261 WE W 263 = E/W
B 257 B B 264 = WEB
260 B /WE / 265 = B/
T 260 T T 266 = /WET

Рис. 4 Процесс распаковки

Выходной поток идентичен входному потоку алгоритма сжатия. Отметим, что первые 256 кодов уже определены для перевода одиночных символов, также как и в алгоритме сжатия.


Ловушка.

К несчастью прекрасный , простой алгоритм распаковки, приведенный на рис. 4, является все таким слишком простым. В алгоритме сжатия существуют некоторые исключительные ситуации, которые создают проблемы при распаковке. Если существует строка, представляющая пару (СТРОКА СИМВОЛ) и уже определенную в таблице, а просматриваемый входной поток содержит последовательность СТРОКА СИМВОЛ СТРОКА СИМВОЛ СТРОКА, алгоритм сжатия выведет код прежде, чем распаковщик получит возможность определить его.

Простой пример иллюстрирует это. Предположим, строка «JOEYN» определена в таблице с кодом 300. Когда последовательность «JOEYNJOEYNJOEY» появляется в таблице, выходной поток алгоритма сжатия выглядит подобно тому, как показано на рис. 5.

Входная строка : . JOEYNJOEYNJOEY.

Вход(символы) Выход(коды) Новые коды и соотв. строки
JOEYN 288 = JOEY 300 = JOEYN
A N 301 = NA
. . .
. . .
. . .
JOEYNJ 300 = JOEYN 400 = JOEYNJ
JOEYNJO 400 401 = JOEYNJO

Рис. 5 Некоторые проблемы

Когда распаковщик просматривает входной поток, он сначала декодирует код 300, затем выводит строку «JOEYN» и добавляет определение для, скажем, кода 399 в таблицу, хотя он уже мог там быть. Затем читает следующий входной код, 400, и обнаруживает, что его нет в таблице. Это уже проблема. К счастью, это произойдет только в том случае, если распаковщик встретит неизвестный код. Так как это фактически единственная коллизия, то можно без труда усовершенствовать алгоритм.

Модифицированный алгоритм предусматривает специальные действия для еще неопределенных кодов. В примере на рис. 6 распаковщик обнаруживает код 400, который еще не определен. Так как этот код не известен, то декодируется значение СТАРОГО_КОДА, равное 300. Затем распаковщик добавляет значение СИМВОЛА, равное «J», к строке. Результатом является правильный перевод кода 400 в строку «JOEYNJ».

читать СТАРЫЙ_КОД
вывести СТАРЫЙ_КОД
СИМВОЛ = СТАРЫЙ_КОД
WHILE входной поток не пуст DO
читать НОВЫЙ_КОД
IF NOT в таблице перевода НОВЫЙ_КОД THEN
СТРОКА = перевести СТАРЫЙ_КОД
СТРОКА = СТРОКА+СИМВОЛ
ELSE
СТРОКА = перевести НОВЫЙ_КОД
END of IF
вывести СТРОКУ
СИМВОЛ = первый символ СТРОКИ
добавить в таблицу перевода СТАРЫЙ_КОД+СИМВОЛ
СТАРЫЙ_КОД = НОВЫЙ_КОД
END of WHILE

Рис. 6 Модифицированный алгоритм распаковки


Реализация.

Концепции, использованные в алгоритме сжатия, настолько просты, что весь алгоритм может быть записан в несколько строк. Но так как управление построением таблицы требует некоторых специальных действий, реализация несколько более сложна. В демонстрационной программе, приведенной ниже, использовались коды длиной 12, 13 и 14 бит. При длине кода 12 бит потенциально возможно хранить до 4096 строк в таблице. Каждый раз, когда читается новый символ, таблица строк должна просматриваться для сопоставления. Если сопоставление не найдено, новая строка должна быть добавлена в таблицу. Здесь возникают две проблемы. Во-первых, таблица строк может достаточно быстро стать очень большой. Даже если длина строк в среднем ограничивается 3 или 4 символами каждая, верхний предел длин строк может легко превысить 7 или 8 байт на код. К тому же количество памяти, необходимой для хранения строк, заранее не известно, так как оно зависит от общей длины строк.

Вторая проблема заключается в организации поиска строк. Каждый раз, когда читается новый символ, необходимо организовать поиск для новой строки вида СТРОКА+СИМВОЛ. Это означает поддержку отсортированного списка строк. В этом случае поиск для каждой строки включает число сравнений порядка log2 от общего числа строк. Использование 12-битных слов потенциально позволяет выполнять не более 12 сравнений для каждого кода.

Первая проблема может быть решена хранением строк как комбинаций код/символ. Так как каждая строка в действительности является представлением комбинации уже существующего кода и добавочного символа, можно хранить каждую строку как отдельный код плюс символ. Например в разобранном выше примере строка «/WEE» хранится как код 260 и символ «E». Это позволяет использовать для хранения только 3 байта вместо 5 (включающих дополнительный байт для конца строки). Идя назад, можно определить, что код 260 хранится как код 256 плюс добавочный символ «E». Наконец, код 256 хранится как «/» плюс «W».

Выполнение сравнения строк является немного более трудным. Новый метод хранения увеличивает время, необходимое для сравнения строк, но он не влияет на число сравнений. Эта проблема решается использованием алгоритма хэширования для хранения строк. Это означает, что код 256 не хранится в каком-либо массиве по адресу 256, а хранится в массиве по адресу, сформированному на основе самой строки. При определении места хранения данной строки можно использовать тестовую строку для генерации хэш-адреса и затем найти целевую строку однократным сравнением. Так как код для любой данной строки нельзя узнать в дальнейшем иначе как по его позиции в массиве, необходимо хранить код для данной строки совместно с данными строки. В демонстрационной программе для этого используются элементы трех массивов : code_value[i], prefix_code[i] и append_character[i].

Когда необходимо добавить новый код в таблицу, используется хэшфункция в процедуре find_match для генерации корректного i. Процедура find_match генерирует адрес и затем проверяет, не использовался ли он уже. Если это так, то find_match выполняет вторую пробу и так до тех пор, пока не найдется свободное место.

Хэш-функция, использованная в этой программе — простая «xor»-типа хэш-функция. Префикс кода и добавочный символ комбинируются для формирования адреса массива. Если содержимое префикса кода и символ в массиве сопоставляются им, то возвращается корректный адрес. Если элемент массива по этому адресу уже использован, выполняется фиксированное смещение для поиска нового места. Это выполняется до тех пор, пока не будет найдено свободное место или не произойдет сопоставление. Среднее число поисков в такой таблице — меньше 3, если используется таблица на 25% большего размера, чем необходимо. Оно может быть улучшено путем увеличения размера таблицы. Необходимо отметить, что для того, чтобы порядок вторичных проб работал, размер таблицы должен быть простым числом. Это объясняется тем, что проба может быть любым целым между 1 и размером таблицы. Если проба и размер таблицы не являются взаимно простыми, поиск свободных мест может закончиться неудачей, даже если они есть.

Реализация алгоритма распаковки имеет свой набор проблем. Одна из проблем алгоритма сжатия здесь исчезает. Когда выполняется сжатие, необходимо организовать поиск в таблице для данной строки. При распаковке необходимо организовать просмотр для отдельного кода. Это означает, что можно хранить префиксы кодов и добавочные символы, индексируясь по их строковому коду. Это устраняет необходимость в хэш-функции и освобождает массив, использовавшийся для хранения значений кодов.

К сожалению метод, использованный для хранения строковых величин, приводит к тому, что декодировка строк должна выполняться в инверсном порядке. Это значит, что все символы для данной строки при декодировании должны помещаться в стековый буфер, а затем выводиться в обратном порядке. В приведенной программе это выполняется функцией decode_string.

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


Результаты.

Достаточно трудно охарактеризовать результативность какой-либо техники сжатия данных. Степень сжатия определяется различными факторами. LZW-сжатие выделяется среди прочих, когда встречается с потоком данных, содержащим повторяющиеся строки любой структуры. По этой причине он работает весьма эффективно, когда встречает английский текст. Уровень сжатия может достигать 50% и выше. Соответственно, сжатие видеоформ и копий экранов показывает еще большие результаты.

Трудности при сжатии файлов данных несколько больше. В зависимости от данных, результат сжатия может быть как хорошим, так и не очень удовлетворительным. В некоторых случаях «сжатый» файл может превосходить по своим размерам исходный текст. Небольшой эксперимент даст Вам представление о том, хорошо или плохо упаковываются Ваши данные.


Ваша реализация.

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

Одной из проблем является то, что приведенная программа не адаптируется к различной длине файлов. Использование 14- или 15-битных кодов дает лучшую степень сжатия на больших файлах (это объясняется тем, что для них строятся большие таблицы строк), но хуже работает с маленькими файлами. Такие программы, как «ARC», решают эту проблему использованием кодов переменной длины. Например, когда величина next_code находится между 256 и 511, «ARC» читает и выводит 9-битные коды. Когда величина next_code становится настолько большой, что необходимы 10-битные коды, процедуры сжатия и распаковки увеличивают размер кода. Это значит, что 12- и 15-битные варианты программы работают хорошо и на маленьких файлах.

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

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

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

И, наконец, можно брать вырабатываемые LZW-методом коды и пропускать их через адаптирующийся кодирующий фильтр Хаффмана. Это дает несколько большую степень сжатия, но стоимость такой работы более высока, также как и время обработки.

Коротко

Приведенная программа была написана и тестирована на MS-DOS машине и успешно скомпилирована и выполнена с использованием обычного компилятора «C». Она должна нормально работать на любой машине, поддерживающей 16-битный целые и 32-битные длинные целые языка «C».

Реализация компиляторов «C» для MS-DOS обычно создает сложности при использовании массивов больших, чем 64К байт, не позволяя использовать 15- или 16-битные коды в программе. На машинах с другими процессорами, таких как VAX, эти сложности преодолеваются и облегчается использование кодов большей длины.

Отметим, что перевод этого кода на язык ассемблера любой машины, поддерживающей 16- и 32-битную математику, не встретит затруднений и позволит улучшить некоторые характеристики.

Linux.yaroslavl.ru

Учебник РНР
Назад Вперёд

gzcompress — сжимает строку.

Описание

string gzcompress (string data [, int level])

Эта функция возвращает сжатую версию входных данных data , используя формат данных ZLIB, или FALSE , если обнаружена ошибка. Необязательный параметр level может быть задан от 0 — нет сжатия, до 9 — максимальное сжатие.

Примечание: это не то же самое, что gzip-компрессия, которая включает некоторые header-данные. См. в gzencode() о gzip-компрессии.

Проблема кодировки php gzcompress

Привет! Я использовал функцию gzcompress в php, чтобы сжать страницу Google, запрошенную в php curl. Я сохранил его в виде HTML-файла, но в gzuncompress некоторые символы не были правильно декодированы. Страница была из Google lietuvos.

Пожалуйста, дайте мне знать, если я что-то упустил? Спасибо. Введите описание изображения здесь

Учитывая небольшую информацию, которую мы имеем, я предполагаю, что это проблема с переводами строки и с кодировкой, имеющей где-то символ «\0» ( null символ).

Что вы можете сделать, это следующее:

Сожмите страницу и закодируйте в base64:

Чтобы распаковать, декодируйте из base64:

Это гарантирует, что все будет написано и прочитано как есть, с примерно 33% накладных расходов.

Есть и другие решения этой проблемы, но это самое простое.

Как работает gzcompress? — php

Мне интересно, почему мне нужно отключить последние 4 символа после использования gzcompress().

Когда я не вырезал последние 4 символа, источник заканчивается как:

Когда я отключил их, он читает:

Я мог видеть дополнительный N только в инспекторе Chromes Code (не в Firefox, а не в источнике IE). Но в конце кода есть еще четыре символа.

Может ли кто-нибудь объяснить мне, почему мне нужно отключить 4 символа?

    1 2
  • 1 ноя 2020 2020-11-01 17:45:52
  • JochenJung

2 ответа

gzcompress производит вывод, описанный здесь RFC1950, последние 4 байта, которые вы отключаете, являются контрольной суммой adler32. Это кодировка «deflate», поэтому вы должны просто установить «Content-Encoding: deflate» и ничего не манипулировать.

Если вы хотите использовать gzip, используйте gzencode() , который использует формат gzip.

  • 1 ноя 2020 2020-11-01 17:45:53
  • nos

Здесь вы видите, что последние четыре байта — это контрольная сумма Adler-32.

В отличие от этого, формат файла GZIP представляет собой список так называемых членов со следующей структурой:

Как вы можете видеть, GZIP использует контрольную сумму CRC-32 для проверки целостности.

Итак, чтобы проанализировать ваш код:

  • echo «x1fx8bx08x00x00x00x00x00»; — выдает следующие поля заголовка:
    • 0x1f 0x8b — идентификаторы ID1 и ID2, идентификаторы для идентификации формата данных (это фиксированные значения)
    • 0x08 — CM, метод сжатия, который используется; 8 обозначает использование формата сжатия данных DEFLATE (RFC 1951)
    • 0x00 — FLG, флаги
    • 0x00000000 — MTIME, время модификации
    • поля XFL (дополнительные флаги) и ОС (операционная система) задаются с помощью формата сжатия данных DEFLATE
  • echo $index; — выдает сжатые данные в соответствии с форматом сжатия данных DEFLATE
  • echo pack(V, $this->content_crc) . pack(V, $this->content_size); — выдает контрольную сумму CRC-32 и размер несжатых входных данных в двоичном формате
Илон Маск рекомендует:  Удобный интерфейс
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL