Vytvořil jsem v Pythonu komprimovaná data jako zlib:
import zlib
s = '...'
z = zlib.compress(s)
with open('/tmp/data', 'w') as f:
f.write(z)
(nebo jednovrstvý v Shell: echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/data
)
Nyní chci dekomprimovat data v Shell. zcat
ani uncompress
nefungují:
$ 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
Zdá se, že jsem vytvořil soubor typu gzip, ale bez záhlaví. Na manuálové stránce gzip bohužel nevidím žádnou možnost dekomprimovat taková nezpracovaná data a balíček zlib neobsahuje žádný spustitelný nástroj.
Existuje nástroj pro dekomprimaci surových dat zlib?
Je také možné dekomprimovat pomocí standardního Shell-script + gzip , pokud nemáte, nebo chcete použít openssl nebo jiné nástroje.
Trik je předepsat gzip magické číslo a metoda komprese ke skutečným datům z zlib.compress
:
printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - /tmp/data |gzip -dc >/tmp/out
Úpravy:
@ d0sboots komentoval: Pro data RAW Deflate musíte přidat další 2 nulové bajty:
→ "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"
Toto Q na SO poskytuje více informací o tomto přístupu. Odpověď na tuto otázku naznačuje, že je zde také zápatí o velikosti 8 bajtů.
Uživatelé @ Vitali-Kushner a @ mark-bessey hlásili úspěch i se zkrácenými soubory, takže zápatí gzip se nezdá být nutně nutné.
@ tobias-kienzler navrhl tuto funkci pro bashrc :zlipd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - [email protected] |gzip -dc)
zlib-flate -uncompress < FILE
Zkusil jsem to a fungovalo to pro mě.
zlib-flate
lze najít v balíčku qpdf
(v Debianu Squeeze a Fedora 23, podle komentářů v dalších odpovědích)
(Díky uživateli @tino, který to poskytl jako komentář pod odpovědí OpenSSL. Vyrobeno v propper odpovědi pro snadný přístup.
Našel jsem řešení (jedno z možných), používá openssl:
$ openssl zlib -d < /tmp/data
nebo
$ openssl zlib -d -in /tmp/data
* POZNÁMKA: Funkce zlib je zjevně k dispozici v nedávných verzích openssl> = 1.0.0 (OpenSSL musí být nakonfigurováno/vytvořeno pomocí zlib nebo zlib-dynamic, druhá je výchozí)
Doporučuji pigz od Mark Adler , spoluautor komprimační knihovny zlib. Po spuštění pigz
zobrazíte dostupné příznaky.
Všimnete si:
-z --zlib Compress to zlib (.zz) instead of gzip format.
Rozbalit můžete pomocí příznaku -d
:
-d --decompress --uncompress Decompress the compressed input.
Předpokládejme soubor s názvem 'test':
pigz -z test
- vytvoří komprimovaný soubor zlib s názvem test.zzpigz -d -z test.zz
- převede test.zz na dekomprimovaný testovací souborV OSX můžete spustit brew install pigz
Mohlo by to udělat:
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)
Pak to spusťte takto:
$ python expander.py data/*
V systémech MacOS, což je plně kompatibilní s unixovým systémem UNIX (formálně certifikováno!), OpenSSL
nemá podporu zlib
, neexistuje žádná zlib-flate
A zatímco první řešení funguje také jako všechna řešení Python vyžaduje první řešení, aby byla data Zip v souboru a všechna ostatní řešení vás nutí vytvořit skript Python.
Zde je řešení založené na Perlu, které může být použito jako liniové příkazové řádky, získává svůj vstup pomocí STDIN kanálu a funguje mimo krabici s čerstvě nainstalovaným makrem:
cat file.compressed | Perl -e 'use Compress::Raw::Zlib;my $d=new Compress::Raw::Zlib::Inflate();my $o;undef $/;$d->inflate(<>,$o);print $o;'
Příjemnější formát, skript Perl vypadá takto:
use Compress::Raw::Zlib;
my $decompressor = new Compress::Raw::Zlib::Inflate();
my $output;
undef $/;
$decompressor->inflate(<>, $output);
print $output;
Příklad programu zpipe.c
zde nalezen samotného Marka Adlera (přichází s distribucí zdroje knihovny zlib) je velmi užitečný pro tyto scénáře se surovými daty zlib. Zkompilujte s cc -o zpipe zpipe.c -lz
A dekomprimujte: zpipe -d < raw.zlib > decompressed
. Může také provádět kompresi bez příznaku -d
.
Můžete to použít ke kompresi se zlib:
openssl enc -z -none -e < /file/to/deflate
A to deflate:
openssl enc -z -none -d < /file/to/deflate
Během vývoje kódu souvisejícího s eIDAS jsem přišel s bash skriptem, který dekóduje SSO (SingleSignOn) SAMLRequest param, který je obvykle kódován base64 a 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
Můžete to použít jako
> decode_saml_request.sh /path/to/file_with_sso_url
# or
> echo "y00tLk5MT1VISSxJBAA%3D" | decode_saml_request.sh
Skript je publikován také jako Gist zde: https://Gist.github.com/smarek/77dacb9703ac8b715b5eced5314d5085 , takže si nemusím udržovat tuto odpověď, ale budu udržovat zdroj Gist