В моем проекте мне нужно знать, как выглядит заголовок zlib
. Я слышал, что это довольно просто, но я не могу найти описание заголовка zlib.
Например, содержит ли магическое число?
В моем проекте мне нужно знать, как выглядит заголовок zlib
. Я слышал, что это довольно просто, но я не могу найти описание заголовка zlib.
Например, содержит ли магическое число?
0 1
+---+---+
|CMF|FLG|
+---+---+
CMF (метод сжатия и флаги) Этот байт делится на 4-битный метод сжатия и 4- бит в зависимости от метода сжатия.
bits 0 to 3 CM Compression method
bits 4 to 7 CINFO Compression info
CM (метод сжатия)
Это определяет метод сжатия, используемый в файле. CM = 8
обозначает метод "сдувания" с размером окна вверх
до 32K. Это метод, используемый gzip и PNG, и почти все остальное.
CM = 15 зарезервировано.
CINFO (информация о сжатии) Для CM = 8 CINFO является логарифмом базы-2 окна LZ77 размер, минус восемь (CINFO = 7 указывает размер окна 32K). Значения CINFO выше 7, не допускаются в этой версии Спецификация. CINFO не определен в этой спецификации для CM не равно 8.
На практике это означает, что первый байт почти всегда 78
(hex)
FLG (FLaGs) Байт этого байта делится следующим образом:
bits 0 to 4 FCHECK (check bits for CMF and FLG)
bit 5 FDICT (preset dictionary)
bits 6 to 7 FLEVEL (compression level)
Значение FCHECK должно быть таким, чтобы CMF и FLG, если смотреть как 16-разрядное целое число без знака, сохраненное в порядке MSB (CMF * 256 + FLG), кратно 31.
FLEVEL (уровень сжатия)
Эти флаги доступны для использования с помощью специального сжатия
методы. Метод "deflate" (CM = 8
) устанавливает эти флаги как
следующим образом:
0 - compressor used fastest algorithm
1 - compressor used fast algorithm
2 - compressor used default algorithm
3 - compressor used maximum compression, slowest algorithm
Заголовки заголовков zlib
78 01 - No Compression/low
78 9C - Default Compression
78 DA - Best Compression
Заголовки ZLIB/GZIP
Level | ZLIB | GZIP
1 | 78 01 | 1F 8B
2 | 78 5E | 1F 8B
3 | 78 5E | 1F 8B
4 | 78 5E | 1F 8B
5 | 78 5E | 1F 8B
6 | 78 9C | 1F 8B
7 | 78 DA | 1F 8B
8 | 78 DA | 1F 8B
9 | 78 DA | 1F 8B
Deflate не имеет общих заголовков
Ниже приведен формат сжатых данных Zlib.
+---+---+
|CMF|FLG| (2 bytes - Defines the compression mode - More details below)
+---+---+
+---+---+---+---+
| DICTID | (4 bytes. Present only when FLG.FDICT is set.) - Mostly not set
+---+---+---+---+
+=====================+
|...compressed data...| (variable size of data)
+=====================+
+---+---+---+---+
| ADLER32 | (4 bytes of checksum)
+---+---+---+---+
В основном, FLG.FDICT
(флаг словаря) не установлен. В таких случаях DICTID
просто нет. Таким образом, общий объем слышимого составляет всего 2 байта.
Значения заголовка (CMF
и FLG
) без словаря определяются следующим образом.
CMF | FLG
0x78 | 0x01 - No Compression/low
0x78 | 0x9C - Default Compression
0x78 | 0xDA - Best Compression
Подробнее на ZLIB RFC
Заголовок ZLIB (как определено в RFC1950) представляет собой 16-разрядное значение с прямым порядком байтов. Содержит эти поля от самых значимых до наименее значимых:
CINFO
(биты 12-15)
Указывает размер окна в виде степени двойки, от 0
(256 байт) до 7
(32768 байт). Обычно это будет 7
. Более высокие значения не допускаются.
CM
(биты 8-11)
Метод сжатия. Разрешается только Deflate (8
).
FLEVEL
(биты 6-7)
Примерно указывает уровень сжатия от 0
(быстрый/низкий) до 3
(медленный/высокий)
FDICT
(бит 5)
Указывает, используется ли заданный словарь. Обычно это 0
. 1
технически разрешен, но я не знаю ни одного формата Deflate, определяющего предустановленные словари.
FCHECK
(биты 0-4)
Контрольная сумма (5 битов, 0
.. 31
), значение которой рассчитывается так, что все значение делится на 31 без остатка.
Как правило, только поля CINFO
и FLEVEL
могут быть свободно изменены, и FCHECK
должен быть рассчитан на основе конечного значения. * При условии, что нет предустановленного словаря, нет выбора в том, что содержат другие поля, поэтому итого из 32 возможных заголовков действительны. Вот они:
FLEVEL: 0 1 2 3
CINFO:
0 08 1D 08 5B 08 99 08 D7
1 18 19 18 57 18 95 18 D3
2 28 15 28 53 28 91 28 CF
3 38 11 38 4F 38 8D 38 CB
4 48 0D 48 4B 48 89 48 C7
5 58 09 58 47 58 85 58 C3
6 68 05 68 43 68 81 68 DE
7 78 01 78 5E 78 9C 78 DA
Поле CINFO
редко, если вообще когда-либо, устанавливается компрессорами как-либо отличное от 7
(указывающее максимальный размер окна 32 КБ), поэтому единственные значения, которые вы, вероятно, увидите в дикой природе, - это четыре в нижний ряд (начиная с 78
).
* (Вы могли бы задаться вопросом, есть ли небольшая свобода в значении FCHECK
- можно ли установить 0 или 31, если оба проходят контрольную сумму? На практике, однако, в этой ситуации нет действительных заголовков происходит, поэтому нам не нужно беспокоиться об этом.)
Все ответы здесь, скорее всего, правильны, однако, если вы хотите напрямую манипулировать потоком сжатия ZLib, и он был создан с использованием функций gz_open, gzwrite, gzclose
, то есть еще 10 ведущих байтов заголовка до того, как наступает сжатый пар zlib - и те создаются функцией gz_open - заголовок выглядит следующим образом:
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
И приводит к следующему шестнадцатеричному дампу: 1F 8B 08 00 00 00 00 00 00 0B
за которым следует поток сжатия zlib.
Но есть также 8 байтов - они uLong
- crc для всего файла, uLong
- несжатый размер файла - найдите следующие байты в конце потока:
putLong (s->file, s->crc);
putLong (s->file, (uLong)(s->in & 0xffffffff));