Переклад документу RFC1950, який знаходиться за адресою https://www.ietf.org/rfc/rfc1950.txt. В тексті додані посилання на документи-специфікації стандартів, які також перекладені і розміщені на даному сайті.

Статус даного документу

Даний документ надає інформацію для общини Інтернету. Даний документ не визначає будь-який стандарт Інтернету. Розповсюдження даного документу жодним чином не обмежується.

Нотатка IESG:

IESG не займає будь-якої позиції по відповідності тверджень авторського права (Intellectual Property Rights), які розміщені у даному документі.

Ліцензія

Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly Permission is granted to copy and distribute this document for any purpose and without charge, including ranslations into other languages and incorporation into compilations, provided that the copyright notice and this notice are preserved, and that any substantive changes or deletions from the original are clearly marked. Вказівники на найновішу версію даного і пов'язаних документів у форматі HTML знаходяться за URL-адресою <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.

Загальна теорія

Дана специфікація визначає безвтратний формат стиснених даних. Дані можуть бути створеними або отриманими, навіть для доволі довгої послідовності ввідного потоку даних, використовуючи тільки обмежену частину проміжної пам'яті. В даний момент формат використовує метод компресії DEFLATE, але може легко розширюватись для використання інших методів компресії. Він може легко реалізуватися у спосіб, який не закритий патентами. Дана специфікація також визначає контрольну суму ADLER-32 (розширення і покращення контрольної суми Флетчера (Fletcher)), яка використовується для виявлення пошкодження даних, і забезпечує алгоритм для її обчислення.

Вміст

  1. Вступ
    1. Призначення
    2. Цільова аудиторія
    3. Межі застосування
    4. Сумісність
    5. Визначення використовуваних термінів і правил
    6. Зміни з попередньої версії
  2. Детальна специфікація
    1. Загальні правила
    2. Формат даних
    3. Сумісність
  3. Виноски
  4. Джерельний код
  5. Міркування безпеки
  6. Подяки
  7. Адреса авторів
  8. Додаток: Обґрунтування
  9. Додаток: Приклад коду

1. Вступ

1.1 Призначення

Призначення даного документу полягає у визначенні безвтратного формату стиснених даних, які:
  • Незалежний від типу процесора (CPU), операційної системи, файлової системи, і системи символів, що в результаті дає можливість обміну;
  • Може бути створеним або отриманим, навіть для доволі довгих послідовностей ввідного потоку даних, використовуючи тільки обмежену кількість проміжної пам'яті, що дозволяє використовувати його у комунікаціях або подібних структурах на подобі Unix-фільтрів;
  • Може використовувати певну кількість різних методів компресії;
  • Може легко реалізовуватись у спосіб, який не закритий патентами, і отже може вільно практикуватися.
Формат даних визначений у цій специфікації не призначений для довільного доступу до стиснених даних.

1.2 Цільова аудиторія

Дана специфікація призначена для використання розробниками програмного забезпечення для стиснення даних у формат zlib і/або розпаковування даних з формату zlib. Текст специфікації припускає базові знання у програмування на рівні бітів і інших примітивних структур даних.

1.3 Межі застосування

Дана специфікація визначає стиснений формат даних, який може використовуватися для компресії у пам'яті послідовності звичайних байтів.

1.4 Сумісність

Якщо не вказане інше, сумісний декомпресор повинен бути здатним приймати і декодувати будь-який набір даних, який відповідає усім специфікаціям описаним в даному документів; сумісний компресор повинен створювати набір даних, який відповідає усім специфікаціям встановленим у даному документі.

1.5 Визначення використовуваних термінів і правил

байт - зберігається або передається у якості одиниці (те ж саме що і октет). (Для даної специфікації, байт містить тільки 8 бітів, навіть для машин, які зберігають символ у кількості бітів відмінних від 8.) Нижче в документі визначений порядок бітів у байті.

1.6 Зміни з попередньої версії

Версія 3.1 була першою опублікованою версією даної специфікації. У версії 3.2, деяка термінологія була змінена і приклад коду Adler-32 був переписаний для покращення розуміння коду. У версії 3.3, була впроваджена підтримка наперед встановлених словників, і специфікація була переформатована у стиль документів RFC.

2. Детальна специфікація

2.1 Загальні правила

У наведеній нижче діаграмі, дана фігура (псевдографіки):
+---+
|   | <-- вертикальні лінії можуть бути відсутніми
+---+
представляє один байт; фігура на подобі даної:
+==============+
|              |
+==============+
представляє довільну кількість байтів. Байти збережені у комп'ютері не мають "порядок бітів", оскільки вони завжди трактуються у якості одиниці. Однак, байт вважається цілим числом у проміжку від 0 до 255, має найбільш- і найменш значущі біти, і оскільки ми записуємо числа з найбільш значущими числами зліва, ми також записуємо байти з найбільш значущими бітами зліва. У діаграмі наведеній нижче, ми пронумерували біти байту так, що біт 0 являється найменш значущим бітом, тобто біти пронумеровані наступним чином:
+--------+
|76543210|
+--------+
У комп'ютері, число може займати багато байтів. Усі багатобайтні числа у форматі описаному тут зберігаються у найбільш-значущому байті першими (при менших адресах пам'яті). Наприклад, десяткове число 520 зберігається у наступному вигляді:
    0     1
+--------+--------+
|00000010|00001000|
+--------+--------+
^        ^
|        |
|        + менш значущий байт = 8
+ більш значущий байт = 2 x 256

2.2 Формат даних

Потік даних zlib має наступну структуру:
  0   1
+---+---+
|CMF|FLG|   (далі-->)
+---+---+

(якщо встановлений FLG.FDICT)

  0   1   2   3
+---+---+---+---+
|     DICTID    |   (далі-->)
+---+---+---+---+

+=====================+---+---+---+---+
|....стиснені дані....|    ADLER32    |
+=====================+---+---+---+---+

Будь-які дані, які можуть бути розміщеними після поля ADLER32 не являються частиною потоку даних zlib.

CMF (Метод компресії і прапорці - Compresion Method and flags)

Даний байт розділяється на 4-бітне поле методу компресії і 4-бітне інформаційне поле, яке залежить від методу компресії.
біти від 0 до 3   CM      Метод компресії
біти від 4 до 7   CINFO   Інформація компресора

CM (Метод Компресії - Compression method)

Дане поле ідентифікує метод компресії, який використовується у файлі. Значення CM=8 визначає метод компресії "deflate" з можливим розміром вікна у 32 Кбайти. Даний метод використовується у gzip і PNG (перегляньте виноски [1] і [2] у параграфі 3 нижче за відповідними документами). Значення CM=15 являється зарезервованим. Він може використовуватися у майбутніх версіях даної специфікації для вказування присутності додаткових полів перед стисненими даними.

CINFO (Інформація компресора - Compression info)

Для значення CM=8, CINFO являється логарифмом з базою 2 розміру вікна LZ77 мінус вісім (CINFO=8 вказує на вікно у 32 Кбайти). Значення CINFO вище за 7 не доступні у даній версії специфікації. CINFO не визначений у даній специфікації для CM не рівного 8.

FLG (прапорці - FLaGs)

Даний байт прапорців визначається наступним чином:
біти від 0 до 4    FCHECK      (біти перевірки для CMF і FLG)
біт 5              FDICT       (встановлений словник)
біти від 6 до 7    FLEVEL      (метод компресії)
Значення FCHECK повинне бути таким, що під час відношення CMF і FLG у якості 16-бітного цілочисельного значення збереженого у порядку MSB (найбільш значущого байту - CMF*256 + FLG), у якості множника 31.

FDICT (Наперед встановлений словник - Preset dictionary)

Якщо FDICT встановлено, ідентифікатор словника DICT розміщений одразу після байту FLG. Словник являється послідовністю байтів, який встановлений у компресорі без створення будь-якого стисненого виводу. DICT являється контрольною сумою ADLER32). Декомпресор може використовувати даний ідентифікатор для визначення словника, який використовувався компресором.

FLEVEL (Рівень компресії - Compression Level)

Дані прапорці доступні для використання певними методами компресії. Метод компресії "deflate" (CM=8) встановлює дані прапорці наступним чином:
  • 0 - компресор використовує найшвидший алгоритм
  • 1 - компресор використовує швидкий алгоритм
  • 2 - компресор використовує алгоритм за умовчанням
  • 3 - компресор використовує максимальну компресію, найповільніший алгоритм.
Інформація у FLEVEL не потребує декомпресії; вона розміщується там для визначення того, чи повторна компресія буде відповідати витраченим зусиллям.

Стиснені дані

Для методу компресії 8, стиснені дані зберігаються у якості стиснених даних формату deflate, як описано у документі "DEFLATE Compressed Data Format Specification" (перегляньте виноску [3] нижче у параграфі 3) (переклад на kytok.org.ua - Специфікація формату DEFLATE - RFC1951). Інші формати стиснених даних не вказані у даній версії специфікації формату zlib.

ADLER32 (Контрольна сума Adler-32)

Дане поле містить значення контрольної суми нестиснених даних (не включаючи будь-які дані словника), яке обчислене за допомогою алгоритму Adler-32. Даний алгоритм являється 32-х бітним розширенням і покращенням алгоритму Флетчера (Fletcher), який використовується у стандарті ITU-T X.224/ISO 8073. (Перегляньте виноски [4] i [5] нижче у параграфі 3). Adler-32 скомпонований з двох сум отриманих з байтів: s1 являється сумою усіх байтів, s2 являється сумою усіх значень s1. Обидві суми виконуються по модулю 65521. s1 ініціалізується у 1, s2 у нуль. Контрольна сума Adler-32 зберігається у якості s2*65536 + s1 у порядку розміщення значущих байтів першими (мережевий порядок).

2.3 Сумісність

Сумісний компресор повинен створювати потоки з коректними CMF, FLG і ADLER32, але не потребує підтримки наперед встановлених словників. Коли формат даних zlib використовується у якості іншого стандарту формату даних, компресор може використовувати тільки наперед встановлені словники, які і визначаються іншим форматом даних. Якщо даний інший формат не використовує наперед визначені словники, компресор не повинен встановлювати прапорець FDICT. Сумісний декомпресор повинен перевіряти CMF, FLG i ADLER32 і забезпечувати перевірку помилки, якщо будь-які з даних полів містять некоректні значення. Сумісний декомпресор повинен показувати повідомлення про помилку, якщо CM не встановлено у одне з значень, які визначені у даній специфікації (у даній версії дозволено тільки значення 8), оскільки інше значення може показувати присутність нових можливостей, які можуть спричинити неправильне інтерпретування даних. Сумісний декомпресор повинен показувати повідомлення про помилку, якщо FDICT встановлено і DICTID не являється ідентифікатором відомого наперед визначеного словника. Декомпресор може ігнорувати FLEVEL і все-одно бути сумісним. Коли формат даних zlib використовується у якості частини іншого стандарту формату даних, сумісний декомпресор повинен підтримувати усі наперед визначені словники, які визначаються іншим стандартом. Коли інший формат не використовує наперед визначені словники, сумісний декомпресор повинен відкидати будь-який потік, у якому встановлений прапорець FDICT.

3. Виноски

[1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", доступний за адресою ftp://ftp.uu.net/pub/archiving/zip/doc/ [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", доступний за адресою ftp://ftp.uu.net/graphics/png/documents/ (переклад на сайті kytok.org.ua - Специфікація формату графічних файлів Portable Network Graphics (PNG), друга редакція) [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", доступний за адресою ftp://ftp.uu.net/pub/archiving/zip/doc/ (переклад на сайті kytok.org.ua - Cпецифікація алгоритму стискання даних формату DEFLATE версія 1.3 (RFC1951)) [4] Fletcher, J. G., "An Arithmetic Checksum for Serial Transmissions," IEEE Transactions on Communications, Vol. COM-30, No. 1, January 1982, pp. 247-252. [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," November, 1993, pp. 144, 145. (доступний за адресою gopher://info.itu.ch). ITU-T X.244 є таким як ISO 8073.

4. Джерельний код

Джерельний код реалізації "zlib"-сумісної бібліотеки на мові програмування C доступний за адресою ftp://ftp.uu.net/pub/archiving/zip/zlib/.

5. Міркування безпеки

Декодери, які не перевіряють контрольну суму ADLER32 можуть являтися суб'єктами невиявлених спотворень даних.

6. Подяки

Торгові марки, які розміщені у даному документі являються власністю їхніх відповідних власників. Джен-Лоуп Ґайлі (Jean-Loup Gailly) і Марк Адлер (Mark Adler) розробили формат zlib і написали відповідне програмне забезпечення, яке описане у даній специфікації. Ґлен Рендерс-Пірсон (Glenn Randers-Pehreson) перетворила даний документ у формат документів RFC і HTML.

7. Адреса авторів

L. Peter Deutsch Aladdin Enterprises 203 Santa Margarita Ave. Menlo Park, CA 94025 Phone: (415) 322-0103 (тільки AM) FAX: (415) 322-1734 EMail: <ghost@aladdin.com> Jean-Loup Gailly EMail: <gzip@prep.ai.mit.edu> Запитання по технічному вмісту даної специфікації можуть надсилатися на Jean-Loup Gailly <gzip@prep.ai.mit.edu> і Mark Adler <madler@alumni.caltech.edu> Додаткові коментарі по даній специфікації можуть надсилатися до L. Peter Deutsch <ghost@aladdin.com> і Glenn Randers-Pehrson <randeg@alumni.rpi.edu>

8. Додаток: Обґрунтування

8.1 Наперед визначені словники

Наперед визначені словники особливо корисні для стиснення коротких ввідних послідовностей. Компресор може витягнути вигоду від контексту словника для кодування введення більш компактно. Декомпресор може ініціалізовуватись у відповідний контекст, віртуально декодуючи ситснену версію словника не генеруючи будь-який вивід. Однак для певних алгоритмів стиснення, на подобі алгоритму delfate, дана операція може досягатися без виконання будь-якої декомпресії. Компресор і декомпресор повинні використовувати абсолютно однакові словники. Словник може бути фіксованим, або може обирати між певною кількістю наперед визначених словників, у відповідності до типу ввідних даних. Декомпресор може визначити, які словники обрані компресором, перевіряючи ідентифікатор словника. Даний документ не визначає вміст наперед визначених словників, оскільки оптимальні словники являються програмно залежними. Стандартні формати даних, які використовують дану можливість специфікації zlib повинні відповідно визначати дозволені словники.

8.2 Алгоритм Adler-32

Алгоритм Adler-32 являється набагато швидшим ніж алгоритм CRC32, однак він все-одно забезпечує дуже низьку ймовірність того, що програма не визначить помилку. Модуль над утримувачем беззнакового цілого з збільшеною потужністю типу (unsigned long) можуть вміщуватися для 5552 байтів, отож час виконання операції модуля є незначною. Якщо байти являються a, b, c, друга сума являється 3a + 2b + c + 3, отож являється позиційно і порядково чутливою, на відміну від першої суми, яка являється просто контрольною сумою. Те що число 65521 являється простим числом важливо для запобігання можливих великих класів двобайтових помилок, які не змінюють перевірки. (Контрольна сума Флетчера (Fletcher) використовує число 255, яке не є простим числом, що робить перевірку Флетчера не чутливою до зміни одного байту 0<->255.) Сума s1 ініціалізується у 1 замість нуля, щоб зробити довжину частини послідовності s2, отож довжина не повинна перевірятися окремо. (Будь-яка послідовність нулів має значення контрольної суми Флетчера (Fletcher) встановлену у 0).

9. Приклад коду

Наступний код на мові програмування C обчислює контрольну суму Adler-32 буфера даних. Він написаний для легкості читання, а не для швидкодії. Приклад коду являє собою код у мові програмування ANSI C. Користувачі, які не використовують мову програмування C можуть з легкістю прочитати даний приклад, за допомогою наступних підказок:
&      Бітовий оператор "І".
>>     Бітовий оператор зсуву вправо. Під час застосування до 
       беззнакової сутності, як тут, зсув вправо вставляє нульові біти 
       зліва.
<<     Бітовий оператор лівого зміщення. Лівий зсув вставляє нульові біти 
       з права.
++     "n++" збільшує змінну n на одиницю.
%      оператор остачі від ділення: a % b являється остачею від
       ділення на b.
Приклад реалізації:
#define BASE 65521 /* найбільше просте число менше ніж 65536 */

/*
Оновляє часткову контрольну суму Adler-32 відносно байтів буферу 
buf[0..len-1] і повертає оновлену контрольну суму. Контрольна 
сума Adler-32 повинна ініціюватися у значення 1.

Приклад використання:

unsigned long adler = 1L ;

while (read_buffer(buffer, length) != EOF)
{
  adler = update_adler32 (adler, buffer, length) ;
}

if (adler != original_adler) error() ;
*/

unsigned long update_adler32 (unsigned long adler,
                              unsigned char *buf, 
                              int len)
{
  unsigned long s1 = adler & 0xffff ;
  unsigned long s2 = (adler >> 16) & 0xffff ;
  int n ;

  for (n = 0; n < len; n++) 
  {
    s1 = (s1 + buf[n]) % BASE ;
    s2 = (s2 + s1)     % BASE ;
  }
  
  return (s2 << 16) + s1 ;
}

/* Повертає контрольну суму adler32 байтів buf[0..len-1] */

unsigned long adler32 (unsigned char *buf, int len)
{
  return update_adler32 (1L, buf, len) ;
}