Используйте zlib inflate() в c для распаковки с помощью PHP ZLIB_ENCODING_RAW закодированных данных

#php #c #c #zlib

#php #c #c #zlib

Вопрос:

Когда я сжимаю строку PHP с помощью encoding ZLIB_ENCODING_DEFLATE и вывожу шестнадцатеричные данные, я могу преобразовать их обратно в исходную строку, используя zlib deflate() в проекте c .

Согласно приведенному здесь примеру ( https://www.php.net/manual/en/function.zlib-encode.php ) :

 <?php
$str = 'hello world';
$enc = zlib_encode($str, ZLIB_ENCODING_DEFLATE);
echo bin2hex($enc);
?>
 

в c , предварительно преобразовав шестнадцатеричную строку в двоичные данные: (упрощенный код)

 z_stream d_stream;

d_stream.zalloc = (alloc_func)0 ;
d_stream.zfree  = (free_func)0 ;
d_stream.opaque = (voidpf)0 

d_stream.next_in  = InBuffer ;
d_stream.avail_in = InBufferLen ;
d_stream.next_out = OutBuffer ;
d_stream.avail_out = OutBufferLen ;

int err = inflateInit(amp;d_stream) ;

while (err == Z_OK)
    err = inflate(amp;d_stream, Z_NO_FLUSH);

err = inflateEnd(amp;d_stream);
 

OutBuffer снова содержит «hello world»

Мне было интересно zlib inflate() , также ли распаковывается PHP сгенерированные через zlib_encode($str, ZLIB_ENCODING_RAW); необработанные данные?

Из документации zlib я думаю, что нет:

Метод сжатия deflate (единственный, который поддерживается в этой версии).

#define Z_DEFLATED 8

Но PHP имя функции zlib_encode() и определение ZLIB_ENCODING_RAW , похоже, предполагают zlib , поддерживает ли это? Если да, то какую функцию и / или параметры я использую?

Ответ №1:

Обозначения PHP (как обычно) сбивают с толку. Я предполагаю, что ZLIB_ENCODING_RAW это означает необработанные данные deflate (согласно RFC 1951), и, похоже, ZLIB_ENCODING_DEFLATE на самом деле это означает данные deflate, завернутые в zlib (согласно RFC 1950).).

Если это правильно, они должны были вызвать их ZLIB_ENCODING_DEFLATE и ZLIB_ENCODING_ZLIB , соответственно. Но я отвлекся.

Вы можете декодировать необработанные данные deflate с помощью библиотеки zlib, используя inflateInit2() вместо inflateInit() , и указав -15 в качестве второго аргумента.

Комментарии:

1. Спасибо, это работает отлично. Сжатые данные (через PHP ) RAW по сути такие же, как DEFLATE и сжатые данные, за исключением того, что в них отсутствуют 2 байта в начале, 4 байта в конце и последние два байта (перед 4-байтовым хвостом) также отличаются.

2. Ваше повторное обозначение «предположения» и предложение о том, как должны были быть названы определения, соответствуют действительности. PHP RAW действительно «сырой» DEFLATE без заголовков и CRC, а PHP DEFLATE действительно является вариантом ZLIB (заголовки и crc).

3. PS игнорируйте мой комментарий о том, что 2 байта отличаются (это было неправильное наблюдение)