読者です 読者をやめる 読者になる 読者になる

GZIPをZlibデータとして読めるのか?

結論

ムリ。

何がしたいの

例えばMySQLGZIPのデータが入ってるとき、誰しもこのデータを文字列関数UNCOMPRESS関数だけで解凍できないのだろうかと思うのでは無いでしょうか。

GZIP

+---+---+---+---+---+---+---+---+---+---+=======================+---+---+---+---+---+---+
|ID1|ID2|CM |FLG|     MTIME     |XFL|OS |...compressed blocks...|     CRC32     |     ISIZE     |
+---+---+---+---+---+---+---+---+---+---+=======================+---+---+---+---+---+---+

GZIPは"\x1F\x8B"ではじまり、少々のヘッダの後圧縮データが続き、CRC32、元データのサイズで終わる。

Zlib

+---+---+=====================+---+---+---+---+
|CMF|FLG|...compressed data...|    ADLER32    |
+---+---+=====================+---+---+---+---+

CMFとFLGの詳細はRFC1950を見ればいいけど、適当なヘッダをでっち上げるという観点だと"\x78\x9C"でよい。のだが、問題は末尾がADLER32だということである。

MySQLのUNCOMPRESS関数

+---+---+---+---+---+---+=====================+---+---+---+---+
|     ISIZE     |CMF|FLG|...compressed data...|    ADLER32    |
+---+---+---+---+---+---+=====================+---+---+---+---+

UNCOMPRESSが解凍できるのは、最初に元データの長さをつけたZlibです。

末尾のADLER32が不正な場合解凍に失敗してNULLにされてしまうので、CRC32しかないGZIPデータからは作ることが出来ません……。

なお、先頭に元データのサイズが必要ならZlibのデータも無理じゃないのか?と思うかもしれませんが、こちらはでたらめでも大丈夫です。たぶんUNCOMPRESSED_LENGTH用?。

まとめ

あきらめてクライアントで解凍しよう。