UNIXでzlibデータを解凍するには?

UNIXでzlibデータを解凍するには?

次のようにPythonでzlib圧縮データを作成しました。

import zlib
s = '...'
z = zlib.compress(s)
with open('/tmp/data', 'w') as f:
    f.write(z)

(またはシェルの1行echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/data:)

では、シェルからデータを解凍したいと思います。動作しませzcatuncompress

$ cat /tmp/data | gzip -d -
gzip: stdin: not in gzip format

$ zcat /tmp/data 
gzip: /tmp/data.gz: not in gzip format

$ cat /tmp/data | uncompress -
gzip: stdin: not in gzip format

gzipに似たファイルを作成しましたが、ヘッダーがないようです。残念ながら、gzipのマニュアルページにはそのような生データを解凍するオプションはなく、zlibパッケージには実行可能なユーティリティは含まれていません。

生のzlibデータを解凍するユーティリティはありますか?

答え1

標準を使用して解凍することもできます。+、持っていない、または使用したい場合または他のツール。
秘訣はあらかじめ追加することだ。gzip マジックナンバーと圧縮方法実際のデータソースzlib.compress:

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - /tmp/data |gzip -dc >/tmp/out

編集:
@ d0sbootsコメント:RAW Deflateデータの場合は、nullバイトを2つ追加する必要があります。
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"

SOに関するこの質問この方法の詳細を確認できます。それに対する答えは、8バイトのフッターもあることを示します。

@Vitali-Kushnerと@mark-besseyのユーザーは、ファイルが切り捨てられても成功を報告するため、gzipフッターは厳密には要求されないようです。

@tobias-kienzlerはこの機能の使用を提案しました。:
zlibd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - "$@" | gzip -dc)

答え2

zlib-flate -uncompress < IN_FILE > OUT_FILE

私はこれを試して、それは私のために働いた。

zlib-flateパッケージで見つけることができますqpdf(他の答えのコメントに従って、Debian Squeeze、Fedora 23、およびMacOSのBrewで)

(OpenSSLの回答の下にこのコメントを提供した@tinoユーザーに感謝します。より簡単にアクセスできるように正解にしました。)

答え3

以下を使用するソリューション(可能な解決策の1つ)が見つかりました。OpenSSL:

$ openssl zlib -d < /tmp/data

または

$ openssl zlib -d -in /tmp/data

*注:zlib機能は最新のopensslバージョン> = 1.0.0で利用可能に見えます(OpenSSLはzlibまたはzlib-dynamicオプションで設定/構築する必要があり、後者はデフォルトです)。

答え4

POSIXと完全に互換性のあるUNIX(正式に認証されています!)であるmacOSでは、どちらもサポートされていOpenSSLません。最初のソリューションはすべてのPythonソリューションと同じように機能しますが、最初のソリューションではZIPデータが次の場所にある必要があります。ファイルを使用すると、Pythonスクリプトを生成する必要があります。zlibzlib-flate

以下は、コマンドラインシングルライナーとして使用でき、STDINパイプを介して入力を受け取り、新しいmacOSのインストール時にすぐに使用できるPerlベースのソリューションです。

cat file.compressed | perl -e 'use Compress::Raw::Zlib;my $d=new Compress::Raw::Zlib::Inflate();my $o;undef $/;$d->inflate(<>,$o);print $o;'

Perl スクリプトは、次の形式で構成することをお勧めします。

use Compress::Raw::Zlib;
my $decompressor = new Compress::Raw::Zlib::Inflate();
my $output;
undef $/;
$decompressor->inflate(<>, $output);
print $output;

Marco d'Itriの最適化されたバージョン(コメントを参照):

cat file.compressed | perl -MCompress::Zlib -E 'undef $/;print uncompress(<>)'

関連情報