RFC 1952

GZIP file format specification version 4.3

๐Ÿ“… published May 1996, from ietf

GZIP file format specification version 4.3 ๐ŸŽ€

okay bestie, this one is RFC 1952 ๐Ÿ’– It was written by P. Deutsch from Aladdin Enterprises as part of the Network Working Group, and it's classed as Informational, dated May 1996. It doesn't say it obsoletes or updates anything, so it's giving main character all on its own ๐Ÿฆ‹


Status of This Memo โœจ

This memo gives information to the Internet community ๐Ÿซถ It does not specify an Internet standard of any kind, and distribution of it is unlimited.

IESG Note:

The IESG takes no position on the validity of any Intellectual Property Rights statements in this document.

Notices ๐Ÿ“œ

Copyright (c) 1996 L. Peter Deutsch ๐Ÿ’œ

Permission is granted to copy and distribute this document for any purpose and without charge. That includes translations into other languages and putting it into compilations, as long as the copyright notice and this notice are kept, and any substantive changes or deletions from the original are clearly marked ๐ŸŒˆ

There's a pointer to the latest version of this doc and related documentation in HTML format at ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html ๐Ÿงš

Abstract ๐ŸŒธ

This spec defines a lossless compressed data format that's compatible with the widely used GZIP utility ๐Ÿ’… The format includes a cyclic redundancy check value for detecting data corruption ๐Ÿ‘€ It currently uses the DEFLATE method of compression, but it can be easily extended to use other compression methods. It can also be implemented readily in a manner not covered by patents, which is so iconic ๐Ÿ‘‘

Table of Contents ๐Ÿ“

   1. Introduction ................................................... 2
      1.1. Purpose ................................................... 2
      1.2. Intended audience ......................................... 3
      1.3. Scope ..................................................... 3
      1.4. Compliance ................................................ 3
      1.5. Definitions of terms and conventions used ................. 3
      1.6. Changes from previous versions ............................ 3
   2. Detailed specification ......................................... 4
      2.1. Overall conventions ....................................... 4
      2.2. File format ............................................... 5
      2.3. Member format ............................................. 5
          2.3.1. Member header and trailer ........................... 6
              2.3.1.1. Extra field ................................... 8
              2.3.1.2. Compliance .................................... 9
      3. References .................................................. 9
      4. Security Considerations .................................... 10
      5. Acknowledgements ........................................... 10
      6. Author's Address ........................................... 10
      7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
      8. Appendix: Sample CRC Code .................................. 11

1. Introduction โœจ

1.1. Purpose ๐ŸŽ€

okay so the whole point of this spec is to define a lossless compressed data format that:

  • Is independent of CPU type, operating system, file system, and character set, and hence can be used for interchange ๐ŸŒˆ
  • Can compress or decompress a data stream (as opposed to a randomly accessible file) to produce another data stream, using only an a priori bounded amount of intermediate storage, and hence can be used in data communications or similar structures such as Unix filters ๐Ÿ’–
  • Compresses data with efficiency comparable to the best currently available general-purpose compression methods, and in particular considerably better than the "compress" program ๐Ÿ”ฅ
  • Can be implemented readily in a manner not covered by patents, and hence can be practiced freely ๐Ÿฆ‹
  • Is compatible with the file format produced by the current widely used gzip utility, in that conforming decompressors will be able to read data produced by the existing gzip compressor ๐Ÿซถ

and the stuff it does not try to do is:

  • Provide random access to compressed data ๐Ÿ™ˆ
  • Compress specialized data (e.g., raster graphics) as well as the best currently available specialized algorithms ๐Ÿ’€

1.2. Intended audience ๐Ÿงš

this spec is for implementors of software that compresses data into gzip format and/or decompresses data from gzip format ๐Ÿ’…

it also assumes you have a basic background in programming at the level of bits and other primitive data representations, so bring your bit brain ๐Ÿง โœจ

1.3. Scope ๐Ÿ’œ

the spec covers a compression method and a file format. the file format only assumes that a file can store a sequence of arbitrary bytes ๐Ÿ“ It does not specify any particular interface to a file system, and it doesn't say anything about character sets or encodings, except for file names and comments, which are optional ๐ŸŒธ

1.4. Compliance ๐Ÿ‘‘

unless otherwise indicated below, a compliant decompressor must be able to accept and decompress any file that conforms to all the specifications presented here. a compliant compressor must produce files that conform to all the specifications presented here ๐Ÿซถ The material in the appendices is not part of the specification per se and is not relevant to compliance, so you can relax about those ๐Ÿ™Œ

1.5. Definitions of terms and conventions used ๐Ÿ“œ

byte: 8 bits stored or transmitted as a unit (same as an octet). (For this specification, a byte is exactly 8 bits, even on machines which store a character on a number of bits different from 8.) See below for the numbering of bits within a byte ๐Ÿ”ข

1.6. Changes from previous versions ๐Ÿฆ‹

no technical changes to the gzip format since version 4.1 of this spec, so the format is literally the same vibe ๐Ÿ’… In version 4.2, some terminology was changed, and the sample CRC code was rewritten for clarity. It was also changed to eliminate the requirement for the caller to do pre- and post-conditioning ๐ŸŒˆ And version 4.3 is just a conversion of the spec to RFC style โœจ

2. Detailed specification โœจ

2.1. Overall conventions ๐Ÿ’…

okay so in the diagrams coming up, a little box like this ๐Ÿ“ฆ stands for one byte:

+---+
|   | <-- the vertical bars might be missing
+---+

and a box like this stands for a variable number of bytes ๐ŸŒˆ:

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

bytes sitting inside a computer don't have a "bit order" ๐Ÿคทโ€โ™€๏ธ because they're always treated as one whole unit. BUT a byte viewed as an integer from 0 to 255 does have a most significant bit and a least significant bit! and since we write numbers with the most significant digit on the left, we write bytes with the most significant bit on the left too. so in the diagrams below, bit 0 is the least significant bit, and the bits are numbered like this:

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

this document doesn't get into the order bits of a byte are sent in over a bit-sequential medium, because the data format here is byte-oriented rather than bit-oriented. not our problem, bestie ๐Ÿ’–

inside a computer, a number can take up multiple bytes. every multi-byte number in this format is stored with the least significant byte first (at the lower memory address). for example, the decimal number 520 is stored like this ๐Ÿ“:

    0        1
+--------+--------+
|00001000|00000010|
+--------+--------+
 ^        ^
 |        |
 |        + more significant byte = 2 x 256
 + less significant byte = 8

2.2. File format ๐ŸŽ€

a gzip file is a series of "members" (compressed data sets) ๐Ÿง. the format of each member is in the next section. the members just line up one after another in the file, with no extra info before, between, or after them. super minimal, iconic ๐Ÿ‘‘


2.3. Member format ๐Ÿงฉ

each member is built like this, so study the layout ๐Ÿ™ˆ (the captions tell you which optional bits show up, and when):

   +---+---+---+---+---+---+---+---+---+---+
   |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
   +---+---+---+---+---+---+---+---+---+---+

(if FLG.FEXTRA set)

   +---+---+=================================+
   | XLEN  |...XLEN bytes of "extra field"...| (more-->)
   +---+---+=================================+

(if FLG.FNAME set)

   +=========================================+
   |...original file name, zero-terminated...| (more-->)
   +=========================================+

(if FLG.FCOMMENT set)

   +===================================+
   |...file comment, zero-terminated...| (more-->)
   +===================================+

(if FLG.FHCRC set)

   +---+---+
   | CRC16 |
   +---+---+

   +=======================+
   |...compressed blocks...| (more-->)
   +=======================+

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   |     CRC32     |     ISIZE     |
   +---+---+---+---+---+---+---+---+

2.3.1. Member header and trailer ๐Ÿฆ‹

ID1 (IDentification 1) and ID2 (IDentification 2) ๐Ÿ†”

these two are fixed. ID1 = 31 (0x1f, \037) and ID2 = 139 (0x8b, \213), and together they say "hey, this file is in gzip format!" ๐ŸŽ

CM (Compression Method) ๐Ÿ—œ๏ธ

this tells you which compression method the file uses. CM = 0-7 are reserved. CM = 8 is the "deflate" method, which is the one gzip customarily uses, and it's documented elsewhere ๐Ÿ’œ

FLG (FLaGs) ๐Ÿšฉ

this flag byte is split into individual bits like so:

bit 0   FTEXT
bit 1   FHCRC
bit 2   FEXTRA
bit 3   FNAME
bit 4   FCOMMENT
bit 5   reserved
bit 6   reserved
bit 7   reserved

If FTEXT is set, the file is probably ASCII text. this one's an optional hint ๐ŸŒธ. the compressor can peek at a small chunk of the input and check whether any non-ASCII characters are present, and then set it. in case of doubt, FTEXT gets cleared, which means binary data. for systems with different file formats for ascii text and binary data, the decompressor can use FTEXT to pick the right format. we deliberately don't specify the algorithm for setting this bit, since a compressor always has the option of leaving it cleared, and a decompressor always has the option of ignoring it and letting some other program handle data conversion ๐Ÿซถ

If FHCRC is set, a CRC16 for the gzip header is present, immediately before the compressed data. the CRC16 is the two least significant bytes of the CRC32 for all bytes of the gzip header up to and not including the CRC16. [The FHCRC bit was never set by versions of gzip up to 1.2.4, even though it was documented with a different meaning in gzip 1.2.4.] the tea on that FHCRC bit is WILD ๐Ÿ˜ญ (lol kidding, it's just a fun history bit)

hmm wait, let me redo that last bit clearly: the FHCRC bit was never set by gzip versions up to 1.2.4, even though 1.2.4 documented it with a different meaning. messy history, but that's the tea โ˜•

If FEXTRA is set, optional extra fields are present, as described in a following section ๐ŸŒˆ

If FNAME is set, an original file name is present, terminated by a zero byte. the name must consist of ISO 8859-1 (LATIN-1) characters. on operating systems using EBCDIC or any other character set for file names, the name must be translated to the ISO LATIN-1 character set. this is the original name of the file being compressed, with any directory components removed and, if the file being compressed is on a file system with case insensitive names, forced to lower case. there is no original file name if the data was compressed from a source other than a named file; for example, if the source was stdin on a Unix system, there is no file name ๐Ÿ™ˆ

If FCOMMENT is set, a zero-terminated file comment is present. this comment is not interpreted; it's only intended for human consumption ๐Ÿ’ฌ the comment must consist of ISO 8859-1 (LATIN-1) characters. line breaks should be denoted by a single line feed character (10 decimal) โœจ

Reserved FLG bits must be zero. โš ๏ธ

MTIME (Modification TIME) โฐ

this gives the most recent modification time of the original file being compressed. the time is in Unix format, i.e., seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this may cause problems for MS-DOS and other systems that use local rather than Universal time.) if the compressed data did not come from a file, MTIME is set to the time at which compression started. MTIME = 0 means no time stamp is available ๐Ÿ•ฐ๏ธ

XFL (eXtra FLags) ๐Ÿณ๏ธโ€๐ŸŒˆ

these flags are available for use by specific compression methods. the "deflate" method (CM = 8) sets them like this:

XFL = 2 - compressor used maximum compression,
          slowest algorithm
XFL = 4 - compressor used fastest algorithm

OS (Operating System) ๐Ÿ’ป

this identifies the type of file system where compression took place. that can be useful for figuring out the end-of-line convention for text files ๐Ÿ“ the currently defined values are:

     0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
     1 - Amiga
     2 - VMS (or OpenVMS)
     3 - Unix
     4 - VM/CMS
     5 - Atari TOS
     6 - HPFS filesystem (OS/2, NT)
     7 - Macintosh
     8 - Z-System
     9 - CP/M
    10 - TOPS-20
    11 - NTFS filesystem (NT)
    12 - QDOS
    13 - Acorn RISCOS
   255 - unknown

XLEN (eXtra LENgth) ๐Ÿ“

if FLG.FEXTRA is set, this gives the length of the optional extra field. see below for details ๐Ÿ‘€

CRC32 (CRC-32) ๐Ÿ”

this holds a Cyclic Redundancy Check value of the uncompressed data, computed according to the CRC-32 algorithm used in the ISO 3309 standard and in section 8.1.1.6.2 of ITU-T recommendation V.42. (See http://www.iso.ch for ordering ISO documents. See gopher://info.itu.ch for an online version of ITU-T V.42.) ๐Ÿ“š

ISIZE (Input SIZE) ๐Ÿ“

this holds the size of the original (uncompressed) input data modulo 2^32 ๐Ÿ’…


2.3.1.1. Extra field ๐ŸŒˆ

if the FLG.FEXTRA bit is set, an "extra field" is present in the header, with total length XLEN bytes. it's a series of subfields, each shaped like this:

+---+---+---+---+==================================+
|SI1|SI2|  LEN  |... LEN bytes of subfield data ...|
+---+---+---+---+==================================+

SI1 and SI2 give a subfield ID, typically two ASCII letters with some mnemonic value ๐Ÿ”ค Jean-Loup Gailly <gzip@prep.ai.mit.edu> is maintaining a registry of subfield IDs, so please send him any subfield ID you wish to use ๐Ÿ“ฎ subfield IDs with SI2 = 0 are reserved for future use. the following IDs are currently defined:

SI1         SI2         Data
----------  ----------  ----
0x41 ('A')  0x70 ('P')  Apollo file type information

LEN gives the length of the subfield data, excluding the 4 initial bytes ๐Ÿงฎ


2.3.1.2. Compliance ๐Ÿ‘‘

a compliant compressor must produce files with correct ID1, ID2, CM, CRC32, and ISIZE. it may set all the other fields in the fixed-length part of the header to default values (255 for OS, 0 for all others), but the compressor must set all reserved bits to zero ๐ŸŽ€

a compliant decompressor must check ID1, ID2, and CM, and provide an error indication if any of these have incorrect values. it must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC at least, so it can skip over the optional fields if they're present. it need not examine any other part of the header or trailer. in particular, a decompressor may ignore FTEXT and OS and always produce binary output, and still be compliant ๐Ÿฆ‹

and this part is a big one: a compliant decompressor must give an error indication if any reserved bit is non-zero, since such a bit could indicate the presence of a new field that would cause subsequent data to be interpreted incorrectly. no vibes-based parsing allowed, periodt ๐Ÿ’€๐Ÿ’…

3. References ๐Ÿ“š

okay so the references are basically the spec showing its receipts ๐Ÿงพ here's everything it cites:

  • [1] "Information Processing - 8-bit single-byte coded graphic character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). The ISO 8859-1 (Latin-1) character set is a superset of 7-bit ASCII. Files defining this character set are available as iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
  • [2] ISO 3309
  • [3] ITU-T recommendation V.42
  • [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", available in ftp://ftp.uu.net/pub/archiving/zip/doc/
  • [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
  • [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
  • [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, pp.118-133.
  • [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, describing the CRC concept.

4. Security Considerations ๐Ÿšจ

okay this one is SERIOUS bestie ๐Ÿ˜ญ any data compression method works by squeezing out redundancy in the data. which means if the data gets corrupted, the damage is likely to be severe and hard to fix ๐Ÿ’€ uncompressed text is way more forgiving, since it'll probably still be readable even with a few corrupted bytes in there ๐Ÿ“–

It is recommended that systems using this data format provide some means of validating the integrity of the compressed data, such as by setting and checking the CRC-32 check value. ๐Ÿ›ก๏ธโœจ

5. Acknowledgements ๐Ÿซถ

trademarks cited in this document belong to their respective owners ๐Ÿ’œ

Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, the related software described in this specification. ๐Ÿ‘‘ Glenn Randers-Pehrson converted this document to RFC and HTML format. ๐ŸŒˆ


6. Author's Address ๐Ÿ“ฎ

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>

Questions about the technical content of this specification can be sent by email to:

Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>

Editorial comments on this specification can be sent by email to:

L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>

7. Appendix: Jean-Loup Gailly's gzip utility ๐Ÿงš

the most widely used gzip implementation, and the original documentation this spec is based on, were created by Jean-Loup Gailly <gzip@prep.ai.mit.edu> ๐Ÿ’– since this implementation is a de facto standard, we're mentioning some more of its features here. just know the material in this section is not part of the specification per se, and implementations need not follow it to be compliant ๐Ÿซถ

when gzip compresses or decompresses a file, it preserves the protection, ownership, and modification time attributes on the local file system ๐ŸŒธ that's because the gzip file format has no provision for representing protection attributes itself. the file format does include a modification time, though, so the gzip decompressor has a command line switch that assigns the modification time from the file, instead of the local modification time of the compressed input, to the decompressed output โฐโœจ


8. Appendix: Sample CRC Code ๐Ÿฆ‹

the following sample code is a practical implementation of the CRC (Cyclic Redundancy Check) ๐ŸŽ€ (see also ISO 3309 and ITU-T V.42 for a formal specification, bestie ๐Ÿ“œ)

the sample code is in ANSI C. if you're not a C user, these hints will help you read it ๐Ÿ™ˆ

&      Bitwise AND operator.
^      Bitwise exclusive-OR operator.
>>     Bitwise right shift operator. When applied to an
       unsigned quantity, as here, right shift inserts zero
       bit(s) at the left.
!      Logical NOT operator.
++     "n++" increments the variable n.
0xNNN  0x introduces a hexadecimal (base 16) constant.
       Suffix L indicates a long value (at least 32 bits).

and here's the code ๐Ÿ’…

/* Table of CRCs of all 8-bit messages. */
unsigned long crc_table[256];

/* Flag: has the table been computed? Initially false. */
int crc_table_computed = 0;

/* Make the table for a fast CRC. */
void make_crc_table(void)
{
  unsigned long c;
  int n, k;
  for (n = 0; n < 256; n++) {
    c = (unsigned long) n;
    for (k = 0; k < 8; k++) {
      if (c & 1) {
        c = 0xedb88320L ^ (c >> 1);
      } else {
        c = c >> 1;
      }
    }
    crc_table[n] = c;
  }
  crc_table_computed = 1;
}

/*
   Update a running crc with the bytes buf[0..len-1] and return
 the updated crc. The crc should be initialized to zero. Pre- and
 post-conditioning (one's complement) is performed within this
 function so it shouldn't be done by the caller. Usage example:

   unsigned long crc = 0L;

   while (read_buffer(buffer, length) != EOF) {
     crc = update_crc(crc, buffer, length);
   }
   if (crc != original_crc) error();
*/
unsigned long update_crc(unsigned long crc,
                unsigned char *buf, int len)
{
  unsigned long c = crc ^ 0xffffffffL;
  int n;

  if (!crc_table_computed)
    make_crc_table();
  for (n = 0; n < len; n++) {
    c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
  }
  return c ^ 0xffffffffL;
}

/* Return the CRC of the bytes buf[0..len-1]. */
unsigned long crc(unsigned char *buf, int len)
{
  return update_crc(0L, buf, len);
}
๐Ÿ“ฆ where this page comes from