从截断的 Zip 文件中恢复数据
假设文件只是在vectors.100k.utf8 中间被截断并且损坏并不严重,您应该能够恢复部分数据。您显示的输出确实表明这是一个截断问题。如果没有我请求的 zipdetails 输出,我将无法确定。
如果这只是一个截断问题,您可以解压缩下面的 perl 脚本 recoverzip 中存在的内容。这应该适用于 Windows、MacOS 或 Linux——唯一的先决条件是您需要安装 perl。
use strict ;
use warnings ;
use IO::Uncompress::Unzip qw( unzip $UnzipError );
die "Usage: recoverzip zipfile member outfile
"
if @ARGV != 3;
my $filename = shift;
my $name = shift;
my $outfile = shift;
unzip $filename => $outfile,
Name => $name,
or die "Cannot uncompress '$filename': $UnzipError
" ;
该脚本接受三个参数
- 要处理的 zip 文件的名称
- 要读取的 zip 成员的名称
- 存储恢复数据的输出文件名
此脚本不能保证从截断的 zip 文件中获取任何数据,但在某些情况下可以。这仅取决于截断的位置。
创建截断的 zip 文件
这是一个工作示例,展示它是如何工作的。请注意,我正在使用 Linux 工具生成截断的 zip 文件。恢复部分不依赖于 Linux——只需要在您的系统上安装perl。
首先选择一个输入文件以添加到 zip 文件
$ cat lorem.txt
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
将 lorem.txt 添加到名为 try.zip 的 zip 文件中
$ zip try.zip lorem.txt
$ unzip -l try.zip
Archive: try.zip
Length Date Time Name
--------- ---------- ----- ----
446 2022-09-09 09:17 lorem.txt
--------- -------
446 1 file
现在我们需要在lorem.txt成员的中间截断try.zip。为此,我们需要了解压缩数据在 zip 文件中的位置。可以使用zipdetails 获取该信息。
$ perl zipdetails try.zip
0000 LOCAL HEADER #1 04034B50
0004 Extract Zip Spec 14 '2.0'
0005 Extract OS 00 'MS-DOS'
0006 General Purpose Flag 0000
[Bits 1-2] 0 'Normal Compression'
0008 Compression Method 0008 'Deflated'
000A Last Mod Time 55294A2E 'Fri Sep 9 10:17:28 2022'
000E CRC F90EE7FF
0012 Compressed Length 0000010E
0016 Uncompressed Length 000001BE
001A Filename Length 0009
001C Extra Length 001C
001E Filename 'lorem.txt'
0027 Extra ID #0001 5455 'UT: Extended Timestamp'
0029 Length 0009
002B Flags '03 mod access'
002C Mod Time 631AF698 'Fri Sep 9 09:17:28 2022'
0030 Access Time 631AF698 'Fri Sep 9 09:17:28 2022'
0034 Extra ID #0002 7875 'ux: Unix Extra Type 3'
0036 Length 000B
0038 Version 01
0039 UID Size 04
003A UID 000003E8
003E GID Size 04
003F GID 000003E8
0043 PAYLOAD
0151 CENTRAL HEADER #1 02014B50
0155 Created Zip Spec 1E '3.0'
0156 Created OS 03 'Unix'
0157 Extract Zip Spec 14 '2.0'
0158 Extract OS 00 'MS-DOS'
0159 General Purpose Flag 0000
[Bits 1-2] 0 'Normal Compression'
015B Compression Method 0008 'Deflated'
015D Last Mod Time 55294A2E 'Fri Sep 9 10:17:28 2022'
0161 CRC F90EE7FF
0165 Compressed Length 0000010E
0169 Uncompressed Length 000001BE
016D Filename Length 0009
016F Extra Length 0018
0171 Comment Length 0000
0173 Disk Start 0000
0175 Int File Attributes 0001
[Bit 0] 1 Text Data
0177 Ext File Attributes 81ED0000
017B Local Header Offset 00000000
017F Filename 'lorem.txt'
0188 Extra ID #0001 5455 'UT: Extended Timestamp'
018A Length 0005
018C Flags '03 mod access'
018D Mod Time 631AF698 'Fri Sep 9 09:17:28 2022'
0191 Extra ID #0002 7875 'ux: Unix Extra Type 3'
0193 Length 000B
0195 Version 01
0196 UID Size 04
0197 UID 000003E8
019B GID Size 04
019C GID 000003E8
01A0 END CENTRAL HEADER 06054B50
01A4 Number of this disk 0000
01A6 Central Dir Disk no 0000
01A8 Entries in this disk 0001
01AA Total Entries 0001
01AC Size of Central Dir 0000004F
01B0 Offset to Central Dir 00000151
01B4 Comment Length 0000
Done
zipdetails 有很多输出,但出于我们的目的,我们需要查看PAYLOAD 行——它显示了lorem.txt 的压缩数据开始的偏移量。在这种情况下,它是十六进制 043。下一个字段是 CENTRAL HEADER,偏移量为十六进制 0151。这意味着压缩的有效负载从偏移量 0x43 开始,到 0x150 结束。
现在截断位于lorem.txt 压缩数据中间偏移量 0x100 处的 zip 文件,并将截断的 zip 文件写入 trunc.zip
$ head -c $((0x100)) try.zip >trunc.zip
我们现在有一个示例截断的 zip 文件来测试。首先检查unzip 对截断文件的看法 - 它显示的错误与您的错误非常相似
$ unzip -t trunc.zip
Archive: trunc.zip
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
unzip: cannot find zipfile directory in one of trunc.zip or
trunc.zip.zip, and cannot find trunc.zip.ZIP, period.
从截断的 zip 文件中恢复数据
现在运行 recoverzip 脚本,看看我们是否可以从 zip 文件中获取任何数据。
$ perl recoverzip trunc.zip lorem.txt recovered.txt
Cannot uncompress 'trunc.zip': unexpected end of file
unexpected end of file 错误在这个用例中是意料之中的。
最后,让我们看看恢复了哪些数据
$ cat recovered.txt
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit e
成功!在这种情况下,我们已经从lorem.txt 恢复了一些数据。