次のようにして、Pythonでzlib圧縮データを作成しました。
_import zlib
s = '...'
z = zlib.compress(s)
with open('/tmp/data', 'w') as f:
f.write(z)
_
(またはシェルのワンライナー:echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/data
)
次に、シェルでデータを解凍します。 zcat
もuncompress
も機能しません:
_$ 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データを解凍するユーティリティはありますか?
標準 Shell-script + gzip を使用して解凍することもできます、または openssl を使用していない、または使用したい場合。
コツは、 gzipマジックナンバーを付加し、_zlib.compress
_からの実際のデータにmethod を圧縮することです。
_printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - /tmp/data |gzip -dc >/tmp/out
_
編集:
@ d0sbootsがコメントしました:RAW Deflateデータの場合、さらに2つのnullバイトを追加する必要があります:
→__"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"
_
SOに関するこのQ は、このアプローチに関する詳細情報を提供します。そこでの答えは、8バイトのフッターもあることを示唆しています。
ユーザーの@ Vitali-Kushnerと@ mark-besseyは、ファイルが切り捨てられた場合でも成功したと報告しているため、gzipフッターは厳密には必要ないようです。
@ tobias-kienzlerは bashrc に対してこの関数を提案しました:zlipd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - $@ |gzip -dc)
zlib-flate -uncompress < FILE
私はこれを試してみましたが、うまくいきました。
zlib-flate
はパッケージqpdf
にあります(他の回答のコメントによると、Debian SqueezeおよびFedora 23の場合)
(OpenSSL回答の下にコメントとしてこれを提供したユーザー@tinoに感謝します。簡単にアクセスできるように適切な回答にされました。)
私は解決策を見つけました(可能な解決策の1つ)、それはopensslを使用しています:
$ openssl zlib -d < /tmp/data
または
$ openssl zlib -d -in /tmp/data
*注:最近のopensslバージョン> = 1.0.0でzlib機能が使用できるようです(OpenSSLはzlibまたはzlib-dynamicオプションで構成/構築する必要があります。後者はデフォルトです)
Zlib圧縮ライブラリの共著者である Mark Adler から pigz をお勧めします。 pigz
を実行して、使用可能なフラグを確認します。
君は気づくよ:
-z --zlib Compress to zlib (.zz) instead of gzip format.
-d
フラグを使用して解凍できます。
-d --decompress --uncompress Decompress the compressed input.
「test」という名前のファイルを想定します。
pigz -z test
-test.zzという名前のzlib圧縮ファイルを作成しますpigz -d -z test.zz
-test.zzを解凍されたテストファイルに変換しますOSXではbrew install pigz
を実行できます
zlib
gzipで使用される圧縮を実装しますが、ファイル形式は実装しません。代わりに、それ自体がgzip
を使用する zlib
module を使用する必要があります。
import gzip
s = '...'
with gzip.open('/tmp/data', 'w') as f:
f.write(s)
これはそれを行うかもしれません:
import glob
import zlib
import sys
for filename in sys.argv:
with open(filename, 'rb') as compressed:
with open(filename + '-decompressed', 'wb') as expanded:
data = zlib.decompress(compressed.read())
expanded.write(data)
次に、次のように実行します。
$ python expander.py data/*
完全なPOSIX準拠のUNIX(正式に認定された!)であるmacOSでは、OpenSSL
はzlib
をサポートせず、zlib-flate
もありません。すべてのPythonソリューションでは、最初のソリューションではZipデータがファイルに含まれている必要があり、他のすべてのソリューションではPythonスクリプトを作成する必要があります。
コマンドラインのワンライナーとして使用でき、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;
サンプルプログラムzpipe.c
ここにあります Mark Adler自身(zlibライブラリのソース配布に付属)は、生のzlibデータを使用するこれらのシナリオに非常に役立ちます。 cc -o zpipe zpipe.c -lz
でコンパイルして解凍します:zpipe -d < raw.zlib > decompressed
。 -d
フラグなしで圧縮を行うこともできます。
これを使用してzlibで圧縮できます。
openssl enc -z -none -e < /file/to/deflate
そしてこれは空気を抜くために:
openssl enc -z -none -d < /file/to/deflate
EIDAS関連コードの開発中に、SSO(SingleSignOn)SAMLRequest paramをデコードするbashスクリプトを思いつきました。これは通常、base64とraw-deflate(php gzdeflate)によってエンコードされます
#!/bin/bash
# file decode_saml_request.sh
urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
if [[ $contents == *"SAMLRequest" ]]; then
# extract param SAMLRequest from URL, strip all following params
contents=$(cat ${1} | awk -F 'SAMLRequest=' '{print $2}' | awk -F '&' '{print $1}')
else
# work with raw base64 encoded string
contents=$(cat ${1})
fi
# add gzip raw-deflate header bytes and gunzip (`gzip -dc` can be replaced by `gunzip`)
printf "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00" | cat - <(echo `urldecode $contents` | base64 -d) | gzip -dc
こんな風に使えます
> decode_saml_request.sh /path/to/file_with_sso_url
# or
> echo "y00tLk5MT1VISSxJBAA%3D" | decode_saml_request.sh
スクリプトはGistとしてもここに公開されています: https://Gist.github.com/smarek/77dacb9703ac8b715b5eced5314d5085 この答えは維持しないかもしれませんが、ソースGistは維持します