如何获取 gzip 存档的跟踪数据?

如何获取 gzip 存档的跟踪数据?

我有一个带有跟踪数据的 gzip 存档。如果我使用它打开它,gzip -d它会告诉我:“解压成功,忽略尾随垃圾“(同样gzip -t可以用作检测是否存在此类数据的方法)。

现在我想了解一下这个垃圾,但奇怪的是我找不到任何方法来提取它。gzip -l --verbose告诉我存档的“压缩”大小是文件的大小(即带有尾随数据),这是错误的并且没有帮助。file也没有什么帮助,那么我能做什么呢?

答案1

现在弄清楚如何获取跟踪数据。

我创建了 Perl 脚本,它创建一个包含尾随数据的文件,它很大程度上基于https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=604617#10:

#!/usr/bin/perl
use strict;
use warnings; 

use IO::Uncompress::Gunzip qw(:all);
use IO::File;

unshift(@ARGV, '-') unless -t STDIN;

my $input_file_name = shift;
my $output_file_name = shift;

if (! defined $input_file_name) {
  die <<END;
Usage:

  $0 ( GZIP_FILE | - ) [OUTPUT_FILE]

  ... | $0 [OUTPUT_FILE]

Extracts the trailing data of a gzip archive.
Outputs to stdout if no OUTPUT_FILE is given.
- as input file file causes it to read from stdin.

Examples:

  $0 archive.tgz trailing.bin

  cat archive.tgz | $0

END
}

my $in = new IO::File "<$input_file_name" or die "Couldn't open gzip file.\n";
gunzip $in => "/dev/null",
  TrailingData => my $trailing;
undef $in;

if (! defined $output_file_name) {
  print $trailing;
} else {
  open(my $fh, ">", $output_file_name) or die "Couldn't open output file.\n";
  print $fh $trailing;
  close $fh;
  print "Output file written.\n";
}

答案2

我创建了一个小脚本来查找 gzip 大小:

#!/bin/bash

set -e
gzip=${1:?Inform a gzip file}
size=$(stat -c%s "$gzip")
min=0
max=$size
while true; do
        if head -c "$size" "$gzip" | gzip -v -t - &>/dev/null; then
                echo $size
                break
        else
                case "$?" in
                        1) min=$size ;;
                        2) max=$size ;;
                esac
                size=$(((max-min)/2 + min))
        fi
done

然后你可以用它来提取 gzip 和尾随部分:

file=gzip_with_trailing.gz
gzip_size=$(./find_gzip_size "$file")
head -c "$gzip_size" "$file" > data.gz
tail -c +$((1+gzip_size)) "$file" > trailing.raw

head/tail 不是最快的解决方案,但它会起作用。

相关内容