March 2018
zip.gz contains gz.zip.
gz.zip contains zip.gz.
A quine is a program, which doesn't take any input and produces its own source code as output. Equivalently it's possible to create archive files, which contain compressed versions of themselves. Quines are not particularly useful, but writing them can be educational and fun.
In order to make the task even more interesting, I decided to create a ZIP file, which (instead of containing itself) contains a GZIP file, which contains the original ZIP file again. ZIP and GZIP files can both employ the DEFLATE compression algorithm, which allows the files to share most of their structure.
Archive files contain not only compressed data, but also some meta-data such as the names and sizes of the contained files and checksums. In this particular case each file starts off with some meta-data (the header), which is followed by the compressed data and final block of meta-data (the footer).
The DEFLATE-compressed data itself consists of compressed and non-compressed blocks. A non-compressed block contains some byte-aligned data prefixed with its length, while a compressed block contains a length and a distance, which cause previously decoded data to be repeated.
# gzip header 1f 8b # magic 08 # compression method (8 = DEFLATE) 08 # flags (8 = has a name) ?? ?? ?? ?? # modification time 00 # extra flags 00 # OS (00 = FAT, ..., ff = unknown) 67 7a 2e 7a 69 70 00 # filename (gz.zip) 00 3f 00 c0 ff # print headers # zip header 50 4b 03 04 # local file header signature 14 00 # version needed to extract 00 00 # general purpose bit flag 08 00 # compression method (8 = DEFLATE) ?? ?? # last modification time ?? ?? # last modification date ?? ?? ?? ?? # crc-32 of the gzip file 16 01 00 00 # compressed size (278 bytes) 30 01 00 00 # uncompressed size (304 bytes) 06 00 # file name length 00 00 # extra file length 7a 69 70 2e 67 7a # filename (zip.gz) 00 3f 00 c0 ff # print headers # gzip header 1f 8b # magic 08 # compression method (8 = DEFLATE) 08 # flags (8 = has a name) ?? ?? ?? ?? # modification time 00 # extra flags 00 # OS (00 = FAT, ..., ff = unknown) 67 7a 2e 7a 69 70 00 # filename (gz.zip) 00 3f 00 c0 ff # print headers 22 5a 3b # repeat(zip header, print headers) 00 10 00 ef ff # print 16 c2 ae 1d # repeat(gzip header, print headers) 00 10 00 ef ff # print 16 22 5a 3b # repeat(zip header, print headers) 00 10 00 ef ff # print 16 02 f2 41 fc ff 00 # repeat(repeater) 00 06 00 f9 ff # print 6 02 f2 41 fc ff 00 # repeat(repeater) 00 10 00 ef ff # print 16 00 06 00 f9 ff # print 6 02 f2 41 fc ff 00 # repeat(repeater) 00 10 00 ef ff # print 16 42 e7 03 # repeat 16 00 10 00 ef ff # print 16 42 e7 03 # repeat 16 00 10 00 ef ff # print 16 42 e7 03 # repeat 16 00 10 00 ef ff # print 16 42 e7 03 # repeat 16 00 10 00 ef ff # print 16 ?? ?? ?? ?? ?? ?? ?? ?? # arbitrary 82 d1 00 # repeat 8 (repeat 8, print footers) 00 59 00 a6 ff # print footers 82 d1 00 # repeat 8 (repeat 8, print footers) 00 59 00 a6 ff # print footers # repeat(gzip footer) 43 66 03 # zip footer (74 bytes) 50 4b 01 02 # central file header signature 14 00 # version made by 14 00 # version needed to extract 00 00 # flags 08 00 # compression method (8 = DEFLATE) ?? ?? # last modification time ?? ?? # last modification date ?? ?? ?? ?? # crc-32 of the gzip file 16 01 00 00 # compressed size (278 bytes) 30 01 00 00 # uncompressed size (304 bytes) 06 00 # file name length 00 00 # extra field length 00 00 # file comment length 00 00 # disk number start 00 00 # internal file attributes 00 00 00 00 # external file attributes 00 00 00 00 # relative offset of local header 7a 69 70 2e 67 7a # filename (zip.gz) 50 4b 05 06 # end of central dir signature 00 00 # number of this disk 00 00 # number of the disk with the start of the central directory 01 00 # total number of entries in the central directory on this disk 01 00 # total number of entries in the central directory 34 00 00 00 # size of the central directory 3a 01 00 00 # start of the central directory 00 00 # comment length # repeat(zip footer) a3 aa c1 00 # gzip footer ?? ?? ?? ?? # crc-32 of the zip file 84 01 00 00 # uncompressed size (388 bytes) # repeat(zip footer) a3 aa c1 00 # gzip footer ?? ?? ?? ?? # crc-32 of the zip file 84 01 00 00 # uncompressed size (388 bytes)