Go
golang
gzip
zlib
deflate

deflate と zlib と gzip の整理


TL; DR


  • 毎回忘れて調べるので、書き留めておきます

時間のない人向けまとめ



  • deflate = 圧縮アルゴリズム(LZ77 + ハフマン符号)


  • zlib, gzip = 圧縮ライブラリ名 兼 ヘッダ/フッタフォーマットの定義


deflate

Wikipedia: https://ja.wikipedia.org/wiki/Deflate


Deflate(デフレート)とはLZ77とハフマン符号化を組み合わせた可逆データ圧縮アルゴリズム。



zlib

Wikipedia: https://ja.wikipedia.org/wiki/Zlib


zlibは、データの圧縮および伸張を行うためのフリーのライブラリである。

ヘッダーやフッターなどのデータ形式はRFC 1950 (ZLIB Compressed Data Format Specification)として仕様化されている。




  • zlib = 圧縮ライブラリ名 兼 ヘッダ/フッタフォーマットの定義

  • 圧縮アルゴリズムは deflate を使用

  • Golangのパッケージ: https://golang.org/pkg/compress/zlib/


gzip

Wikipedia: https://ja.wikipedia.org/wiki/Gzip


gzip(ジー・ジップ)は、データ圧縮プログラムのひとつ、およびその圧縮データのフォーマットである。

フォーマットはRFC 1952 「GZIP File Format Specification」として文書化されている。




  • gzip = 圧縮ライブラリ名 兼 ヘッダ/フッタフォーマットの定義

  • 圧縮アルゴリズムは deflate を使用

  • Golangのパッケージ: https://golang.org/pkg/compress/gzip/


おまけ: Context Takeover (WebSocket)

RFC: https://tools.ietf.org/html/rfc7692#section-7


The term "use context takeover" used in this section means that the

same LZ77 sliding window used by the endpoint to build frames of the

previous sent message is reused to build frames of the next message

to be sent.




  • context takeover = deflate 圧縮の LZ77 ウィンドウを引き継ぐこと


  • gzip の context-takeover とかは 誤用なので注意


おまけ: Content-Encoding: deflate について



  • deflate の 生ストリームではなく、 zlib 形式なので注意

HTTP圧縮でdeflateではなくgzipが採用される理由とは?


HTTPのヘッダー上では、zlibヘッダー付きのdeflateをdeflateと指定するのですが(RFC2616の3.5節)、名前のせいで生のdeflateストリームとしてしまうプログラムがあるようで、うまくやりとりが出来ないことがあるため、多少バイトが増えてもより安全なgzipが使われる、とのことです


Golangにて"compress/flate"パッケージがflateで圧縮したデータを復元できなかった件について


調べたところ、この スレード のように、入力データは Zlib のストリームなので、 compress/zlib を使うべきだった。

なんでクライアントが Zlib のデータなのに Content-Encoding に deflate 設定したのだろう。