RFC 1951 DEFLATE Compressed Data Format Specification version 1.3

Network Working Group                                         P. Deutsch
Request for Comments: 1951                           Aladdin Enterprises
Category: Informational                                         May 1996

DEFLATE Compressed Data Format Specification version 1.3

Формат сжатия данных DEFLATE, версия 1.3

PDF

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

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

Примечание IESG

IESG не занимает какой-либо позиции в отношении заявлений о правах интеллектуальной собственности, содержащихся в документе.

Уведомления

Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly.

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

Указатель на последнюю версию этого документа и связанных с ним документов в формате HTML можно получить по ссылке URL <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.

Аннотация

Эта спецификация задаёт формат сжатых без потерь данных, в котором сжатие выполняется на основе алгоритма LZ77 в сочетании с кодированием Хаффмана (Huffman), а эффективность сравнима с лучшими из доступных на данный момент методами сжатия общего назначения. Данные можно создавать и потреблять даже как последовательность произвольной длины в форме входного потока, используя лишь заведомо ограниченное по размеру промежуточное хранилище. Формат можно легко реализовать без использования патентов.

1. Введение

1.1. Цель

Целью данной спецификации является определение формата сжатия данных без потерь, который:

  • не зависит от типа CPU, файловой системы, набора символов и пригоден для обмена данными;

  • может создаваться и потребляться для сколь угодно длинной последовательности входных данных, используя лишь заведомо ограниченный объём промежуточного хранилища, и пригоден для обмена данными и структур, похожих на фильтры Unix;

  • сжимает данные с эффективностью, близкой к эффективности доступных в данный момент лучших методов сжатия общего назначения и, в частности, значительно лучше программы compress;

  • может быть легко реализован без использования патентов и поэтому может применяться свободно;

  • совместим с форматом файлов широко распространённой утилиты gzip, чтобы поддерживающие этот формат декомпрессоры могли читать данные, созданные имеющимися компрессорами gzip.

Заданный здесь формат данных не пытается:

  • обеспечить произвольный доступ к сжатым данным;

  • сжимать специальные данные (например, растровую графику) так же хорошо, как лучшие из доступных специализированных алгоритмов.

Простой расчёт показывает, что ни один алгоритм сжатия без потерь не подойдёт для всех возможных наборов данных на входе. Для описанного здесь формата размер возрастает в худшем случае на 5 байтов для блока в 32K, т. е. на 0,015% для большого набора данных. Английский текст сжимается в 2,5 — 3 раза, исполняемые файлы обычно сжимаются чуть меньше, а графические данные, такие как растровые изображения, — значительно сильнее.

1.2. Целевая аудитория

Эта спецификация предназначена для разработчиков программ сжатия данных в формат deflate и/или распаковки сжатых данных deflate.

Текст спецификации предполагает базовые знания в сфере программирования на уровне битов и других примитивов представления данных. Знакомство с методами кодирования Хаффмана будет полезно, но не требуется.

1.3. Область действия

Спецификация задаёт метод представления последовательности байтов в виде последовательности битов (обычно более короткой) и метод упаковки полученной последовательности битов в байты.

1.4. Соответствие

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

1.5. Используемые термины и соглашения

byte — байт

8 битов, сохраняемых или передаваемых как единое целое (то же, что и октет). В этой спецификации байт всегда состоит из 8 битов, даже на машинах, где один символ представляется иным число битов. Нумерация битов в байте описана ниже.

string

последовательность произвольных байтов.

1.6. Отличия от предыдущих версий

Формат deflate не претерпел технических изменений по сравнению с версией 1.1. В версии 1.2 изменены некоторые термины, версия 1.3 является просто преобразованием в формат RFC.

2. Обзор сжатого представления

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

Каждый блок сжимается с использованием комбинации алгоритма LZ77 и кодирования Хаффмана. Деревья Хаффмана для каждого блока не зависят от деревьев предыдущих и последующих блоков. Алгоритм LZ77 может использовать ссылку на дубликат строки в предыдущем блоке, если она была во входных данных не более чем на 32K байтов раньше. Каждый блок состоит из двух частей — пары деревьев кода Хаффмана, описывающих представление сжатых данных и сами сжатые данные (сами деревья Хаффмана сжимаются с помощью кодов Хаффмана). Сжатые данные состоят из серий элементов двух типов — литеральные байты (строки, которые не были отмечены как дубликаты содержимого предшествующих 32K байтов входных данных) и указатели на строки-дубликаты, представляемые парой <размер, расстояние>. Представление в формате deflate ограничивает расстояние значением 32K байтов, а размер — значением 258 байтов, но не ограничивает размер блока, за исключением несжимаемых, как указано выше.

Каждый тип значений (литералы, расстояния, размеры) в сжатых данных представляется с использованием кода Хаффмана. Одно дерево кодов служит для литералов и размеров, другое — для расстояний. Деревья кодов для каждого блока представляются в компактной форме непосредственно перед сжатыми данными этого блока.

3. Подробная спецификация

3.1. Базовые соглашения

На рисунках ниже прямоугольники вида

         +---+
         |   | <-- вертикальная черта может отсутствовать
         +---+

представляют 1 байт, а прямоугольники вида

         +==============+
         |              |
         +==============+

— переменное число байтов.

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

         +--------+
         |76543210|
         +--------+

В компьютере число может представляться несколькими байтами. Для всех многобайтовых чисел в документе младший байт указывается первым (с меньшим адресом в памяти). Например, десятичное число 520 представляется в виде

             0        1
         +--------+--------+
         |00001000|00000010|
         +--------+--------+
          ^        ^
          |        |
          |        + старший байт = 2 x 256
          + младший байт = 8

3.1.1. Упаковка в байты

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

  • Элементы данных упаковываются в байты в порядке возрастания номеров битов в байте (с младшего).

  • Элементы данных, отличные от кодов Хаффмана, упаковываются начиная с младшего бита.

  • Коды Хаффмана упаковываются начиная со старшего бита.

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

3.2. Формат сжатого блока

3.2.1. Краткое описание префиксного кодирования и кода Хаффмана

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

Префиксный код определяется бинарным деревом, в котором два ребра из каждого узла, не являющегося листом, помечены цифрами 0 и 1, а каждый каждый лист однозначно соответствует символу алфавита (помечен им). Кодом символа является последовательность 0 и 1 на рёбрах, ведущих от корня к листу, помеченному данным символом, например

                          /\              Символ    Код
                         0  1             ------    ----
                        /    \                A      00
                       /\     B               B       1
                      0  1                    C     011
                     /    \                   D     010
                    A     /\
                         0  1
                        /    \
                       D      C

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

Для алфавита с известным частотным распределением символов алгоритм Хаффмана позволяет создать оптимальный префиксный код (наиболее часто встречающиеся символы представляются более коротким кодом), который называют кодом Хаффмана (см. [1] в разделе 5).

Отметим, что в формате deflate коды Хаффмана для различных алфавитов должны не превышать по размеру определённое значение. Это ограничение усложняет алгоритм расчёта размера кода на основе частоты встречаемости символов (см. ссылки в разделе 5).

3.2.2. Использование кодирования Хаффмана в формате deflate

Для кодов Хаффмана каждого из алфавитов в формате deflate имеется два дополнительных правила:

  • все коды с одинаковым числом битов упорядочены лексически в соответствии с алфавитом;

  • более короткие коды лексически предшествуют более длинным.

Можно перекодировать приведённый выше пример по этим правилам, предполагая алфавитный порядок ABCD.

 

Символ

Код

A

10

B

0

C

110

D

111

 

Код 0 предшествует коду 10, который предшествует 11x, а 110 и 111 упорядочены лексически.

Исходя из этого правила, можно задать код Хаффмана для алфавита, просто указав число битов кода каждого символа по порядку, и этого достаточно для определения фактических кодов. В примере код полностью определяется последовательностью длин (2, 1, 3, 3). Приведённый ниже алгоритм генерирует коды в виде целых чисел, считываемых от старшего бита к младшему. Размеры кодов указываются в tree[I].Len, коды создаются в виде tree[I].

  1. Рассчитывается число кодов для каждого размера. Пусть bl_count[N] — число кодов размером N, где N >= 1.

  2. Находится численное значение наименьшего кода для каждого размера:

                    code = 0;
                    bl_count[0] = 0;
                    for (bits = 1; bits <= MAX_BITS; bits++) {
                        code = (code + bl_count[bits-1]) << 1;
                        next_code[bits] = code;                }
    
  3. Для каждого размера всем кодам присваиваются последовательные численные значения в соответствии с базой, рассчитанной в п. 2. Кодам, которые никогда не используются (0 битов), недопустимо давать значения.

                for (n = 0;  n <= max_code; n++) {
                    len = tree[n].Len;
                    if (len != 0) {
                        tree[n].Code = next_code[len];
                        next_code[len]++;
                    }
                }

Рассмотрим, например, алфавит ABCDEFGH с длинами кодов (3, 3, 3, 3, 3, 2, 4, 4). После этапа 1 получим

            N      bl_count[N]
            -      -----------
            2      1
            3      5
            4      2

На этапе 2 вычисляются значения next_code

            N      next_code[N]
            -      ------------
            1      0
            2      0
            3      2
            4      14

Этап 3 даёт показанные в таблице значения кодов.

 

Символ

Размер

Код

A

3

010

B

3

011

C

3

100

D

3

101

E

3

110

F

2

00

G

4

1110

H

4

1111

 

3.2.3. Детали формата блока

Каждый блок сжатых данных начинается с 3-битового заголовка — первый бит содержит значение BFINAL, остальные — BTYPE. Отметим, что заголовок не обязан начинаться на границе байта, поскольку блок может не составлять целого числа байтов. Флаг BFINAL должен устанавливаться только в последнем блоке набора данных. Поле BTYPE указывает режим сжатия:

00 — без сжатия

01 — сжатие с фиксированными кодами Хаффмана

10 — сжатие с динамическими кодами Хаффмана

11 — резерв (ошибка)

Единственным различием между двумя вариантами сжатия является способ задания кодов Хаффмана для алфавитов «литерал/размер» и «расстояние». Алгоритм декодирования фактических данных для всех случаев показан ниже.

do
   чтение заголовка блока из входного потока
   if сжатие не применяется
      пропуск всех оставшихся битов текущего частично обработанного байта
      чтение LEN и NLEN (см. следующий параграф)
      копирование LEN байтов данных в выходной поток
   otherwise
      if сжатие с динамическими кодами Хаффмана
         чтение представлений деревьев кода (см. ниже)
            loop (до конца блока)
               декодирование значения литерала/размера из входного потока
               if value < 256
                  копирование значения (байт литерала) в выходной поток
               otherwise
                  if value = 256 (конец блока)
                     выход из цикла loop
                  otherwise (value = 257..285)
                     декодирование расстояния (distance) из входного потока

                     перемещение назад на distance в выходном потоке и
                     копирование length байтов отсюда в выходной поток
            end loop
while не последний блок

Отметим, что ссылка на строку-дубликат может указывать на предыдущий блок, т. е. значение distance может переносить через одну или несколько границ блоков, однако не может выходить за начало выходного потока (приложение, использующее заранее установленный словарь, может отбрасывать часть выходного потока и distance может указывать эту часть). Отметим также, что указанная ссылкой строка может перекрываться с текущей позицией. Например, если последние 2 декодированных байта имеют значения X и Y, ссылка на строку <length = 5, distance = 2> добавит в выходной поток XYXYX.

Далее рассматривается каждый из методов сжатия.

3.2.4. Блоки без сжатия (BTYPE=00)

Все биты входного потока до начала следующего байта игнорируются. Оставшаяся часть блока имеет вид

              0   1   2   3   4...
            +---+---+---+---+================================+
            |  LEN  | NLEN  |...   LEN байтов литералов   ...|
            +---+---+---+---+================================+

где LEN — число байтов данных в блоке, NLEN — дополнение LEN до 1.

3.2.5. Сжатые блоки (коды размера и расстояния)

Как отмечено выше, кодированные блоки данных в формате deflate состоят из последовательностей символов, взятых из трёх концептуально разных алфавитов — байты литералов из алфавита байтовых значений (0..255) и пар <размер, расстояние>, где размер (length) может иметь значение (3..258), а расстояние (distance) — (1..32768). На деле алфавиты литералов и размеров объединены в один алфавит (0..285), где значения 0..255 представляют байты литералов, 256 указывает конец блока, а значения 257..285 указывают коды размера (возможно, в сочетании с дополнительными битами после кода символа), как показано в таблице

Код

Дополнительные биты

Размер

Код

Дополнительные биты

Размер

Код

Дополнительные биты

Размер

257

0

3

267

1

15,16

277

4

67-82

258

0

4

268

1

17,18

278

4

83-98

259

0

5

269

2

19-22

279

4

99-114

260

0

6

270

2

23-26

280

4

115-130

261

0

7

271

2

27-30

281

5

131-162

262

0

8

272

2

31-34

282

5

163-194

263

0

9

273

3

35-42

283

5

195-226

264

0

10

274

3

43-50

284

5

227-257

265

1

11,12

275

3

51-58

285

0

258

266

1

13,14

276

3

59-66

Дополнительные биты следует интерпретировать как машинное целое число, начиная со старшего бита, например, биты 1110 представляют десятичное значение 14.

Код

Дополнит. биты

Расстояние

Код

Дополнит. биты

Расстояние

Код

Дополнит. биты

Расстояние

0

0

1

10

4

33-48

20

9

1025-1536

1

0

2

11

4

49-64

21

9

1537-2048

2

0

3

12

5

65-96

22

10

2049-3072

3

0

4

13

5

97-128

23

10

3073-4096

4

1

5,6

14

6

129-192

24

11

4097-6144

5

1

7,8

15

6

193-256

25

11

6145-8192

6

2

9-12

16

7

257-384

26

12

8193-12288

7

2

13-16

17

7

385-512

27

12

12289-16384

8

3

17-24

18

8

513-768

28

13

16385-24576

9

3

25-32

19

8

769-1024

29

13

24577-32768

3.2.6. Сжатие с фиксированными кодами Хаффмана (BTYPE=01)

Коды Хаффмана для двух алфавитов фиксированы и не представляются в данных явно. Размеры кодов Хаффмана для алфавита literal/length представлены в таблице.

 

Значение

Число битов

Коды

0 — 143

8

00110000 — 10111111

144 — 255

9

110010000 — 111111111

256 — 279

7

0000000 — 0010111

280 — 287

8

11000000 — 11000111

 

Размеры кодов достаточны для генерации фактических значений, как описано выше, и для наглядности представлены в таблице. Значения literal/length 286-287 не встречаются в сжатых данных, но применяются в коде.

Коды расстояний 0-31 представлены 5-битовыми значениями, как показано во второй таблице параграфа 3.2.5. Отметим, что коды 30-31 никогда не встречаются в сжатых данных.

3.2.7. Сжатие с динамическими кодами Хаффмана (BTYPE=10)

Коды Хаффмана для двух алфавитов размещаются в блоке сразу после битов заголовка и непосредственно перед сжатыми данными. Сначала указывается код literal/length, затем — код distance. Каждый код задаётся последовательностью длин кодовых слов, как указано в параграфе 3.2.2. Для более компактного представления последовательности длин кодов также сжимаются с помощью кодов Хаффмана. Алфавит размеров кодовых слов показан ниже.

0 — 15

Представляют размеры кодов от 0 до 15.

16

Задаёт копирование предыдущего размера от 3 до 6 раз. Следующие 2 бита указывают число повторов (0 = 3, … , 3 = 6). Например, коды 8, 16 (+2 бита 11), 16 (+2 бита 10) преобразуются в 12 кодов размером 8 (1 + 6 + 5).

17

Задаёт повтор кода размером 0 от 3 до 10 раз (размер 3 бита).

18

Задаёт повтор кода размером 0 от 11 до 138 раз (размер 7 битов).

Размер кода 0 указывает, что соответствующий символ алфавита literal/length или distance не появляется в блоке и его не следует учитывать в описанном ранее построении кода. Если используется только один код расстояния, его следует представлять одним битом (не 0), в этом случае размер кода равен 1 и один из кодов не используется. Один код расстояния с 0 битов означает, что коды расстояния не используются (все данные являются литералами).

Ниже приведено определение формата блока.

5 битов: HLIT,  # коды Literal/Length - 257 (257 - 286)
5 битов: HDIST, # коды Distance - 1         (1 - 32)
4 бита:  HCLEN, # коды размеров кода - 4    (4 - 19)
(HCLEN + 4) x 3 битов: размеры кодов для алфавита размеров кода, 
                       приведённых выше в порядке 16, 17, 18, 0, 8, 7, 
                       9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
                Эти размеры кодов интерпретируются как 3-битовые целые
                числа (0-7); размер кода 0 означает, что соответствующий
                символ (код literal/length или distance) не используется
HLIT + 257      размеры кодов для алфавита literal/length, указанные с 
                использованием кода Хаффмана для размера кода
HDIST + 1       размеры кодов для алфавита distance, указанные с
                использованием кода Хаффмана для размера кода

Фактические сжатые данные блока кодируются с применением кодов Хаффмана для literal/length и distance. Символ literal/length 256 (конец данных), представляется с использованием кода Хаффмана literal/length.

Коды повторения размеров кодов могут варьироваться в размере от HLIT + 257 до HDIST + 1. Иными словами, размеры кодов образуют одну последовательность из HLIT + HDIST + 258 значений.

3.3. Соответствие

Компрессор может дополнительно ограничивать диапазоны значений, указанные в предыдущем параграфе, не теряя совместимости со спецификацией. Например, он может ограничить диапазон указателей назад неким значением меньше 32K. Можно также ограничивать размер блоков для того, чтобы сжимаемый блок помещался в память.

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

4. Детали алгоритма сжатия

Хотя целью документа является задание формата сжатых данных deflate без указания конкретного алгоритма сжатия, описанный здесь формат связан с результатами сжатия LZ77 (Lempel-Ziv 1977, [2]). Многие варианты LZ77 запатентованы, поэтому разработчикам компрессоров настоятельно рекомендуется следовать представленному здесь базовому алгоритму, с которым, как известно, не связано патентов. Приведённые в этом разделе сведения не являются частью спецификации, как таковой, и компрессор не обязан точно следовать им для сохранения соответствия.

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

Компрессор использует связную (chained) хэш-таблицу для поиска строк-дубликатов, применяя хэш-функцию, работающую с 3-байтовыми последовательностями. Пусть для любого момента сжатия XYZ — 3 следующих входных байта для проверки (не обязательно разные). Сначала компрессор проверяет хэш-цепочку для XYZ. Если цепочка пуста, компрессор просто передаёт X на выход как литеральный байт и переходит к следующему входному байту. Непустая цепочка указывает, что последовательность XYZ (или, при неудаче, другие 3 байта с тем же хэш-значением) встречалась недавно, компрессор сравнивает все строки связной хэш-таблицы XYZ с фактическими входными данными, начиная с текущей позиции, и выбирает самое длинное совпадение.

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

Для повышения суммарной степени сжатия компрессор может откладывать выбор совпадений (lazy matching1) — после обнаружения совпадения длиной N байтов компрессор ищет более длинное совпадение, начиная со следующего входного байта. Если такое совпадение найдено, прежнее совпадение отсекается до размера в 1 байт (это ведёт к одному литеральному байту на выходе), а затем выводится найденное совпадение. В ином случае выдаётся исходное совпадение с перемещением на N байтов перед продолжением.

Рабочие (run-time) параметры также влияют на процедуру «ленивого сопоставления». Если важнее всего степень сжатия, компрессор пытается завершить второй поиск независимо от длины первого совпадения. В обычном случае при «достаточно большом» текущем совпадении компрессор сокращает поиск более длинного совпадения, чтобы ускорить процесс. Если важнее скорость, компрессор вставляет в хэш-таблицу новые строки лишь при отсутствии или «слишком большой» длине совпадения. Это снижает степень сжатия, но сокращает время, поскольку уменьшается число вставок и операций поиска.

5. Литература

[1] Huffman, D. A., «A Method for the Construction of Minimum Redundancy Codes», Proceedings of the Institute of Radio Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.

[2] Ziv J., Lempel A., «A Universal Algorithm for Sequential Data Compression», IEEE Transactions on Information Theory, Vol. 23, No. 3, pp. 337-343.

[3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, available in ftp://ftp.uu.net/pub/archiving/zip/doc/

[4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/

[5] Schwartz, E. S., and Kallick, B. «Generating a canonical prefix encoding.» Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.

[6] Hirschberg and Lelewer, «Efficient decoding of prefix codes,» Comm. ACM, 33,4, April 1990, pp. 449-459.

6. Вопросы безопасности

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

Системам, использующим описанный здесь формат данных, рекомендуется обеспечивать те или иные средства проверки целостности сжатых данных (см, например, [3]).

7. Исходный код

Исходный код реализации совместимого с deflate компрессора и декомпрессора доступен в составе пакета zlib по ссылке ftp://ftp.uu.net/pub/archiving/zip/zlib/.

8. Благодарности

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

Фил Кац (Phil Katz) разработал формат deflate. Жан-Лу Гайи (Jean-Loup Gailly) и Марк Адлер (Mark Adler) написали программы, указанные в этой спецификации. Глен Рандерс-Персон (Glenn Randers-Pehrson) преобразовал документ в формат RFC и HTML.

9. Адрес автора

L. Peter Deutsch

Aladdin Enterprises

203 Santa Margarita Ave.

Menlo Park, CA 94025

Phone: (415) 322-0103 (AM only)

FAX: (415) 322-1734

EMail: <ghost@aladdin.com>

Технические вопросы по данной спецификации можно направлять по электронной почте 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>


Перевод на русский язык

Николай Малых

nmalykh@protokols.ru


1Ленивое сопоставление.

Запись опубликована в рубрике RFC. Добавьте в закладки постоянную ссылку.

Добавить комментарий