zl程序教程

您现在的位置是:首页 >  大数据

当前栏目

使用 PAR2 为数据纠错恢复

数据 使用 恢复 纠错
2023-06-13 09:18:39 时间

引:

如果你是通过搜索找到本文,请注意,本文内容不适用于文件误删恢复、已经损坏的文件且无 PAR 2 恢复数据的情况。

1. 序

我们存放在存储、传输数据的过程中,往往可能伴随着很多不确定性,由于各方面原因,文件损坏也时有发生,特别是在某些网络存储平台显得更为常见,有的时候从 A 地将数据打包上传到网盘,从 B 地进行下载,尝试解包过程发生了数据错误,就很糟糕,例如这样:

损坏的压缩包

在面对这个问题的时候,第一时间想到的是某个层面上家喻户晓的 WinRAR 提供的一个功能:恢复记录,确实通过它可以对文件进行修复,而且也是一个很方便的工具,如果希望使用这个方法可以查看:这一部分内容

但不容忽视的是,WinRAR 是一个商业软件,并不是所有情况下它都可以被使用,据个人了解的所有主流压缩格式中,只有 RAR 格式是支持恢复信息的,如果不使用 RAR,那就需要其他方式来进行数据的恢复。

2. 基础概念

如果你想大概了解其原理(为什么它可以这样?),那可以看看这部分内容。

2.1. 纠错码

纠错码(ECC,error correction/correcting code)是信息传输中错误检测与纠正的工具。

查看维基百科上的纠错码词条

看不了维基百科的话也可以看看百度百科

纠错码分为两大类:分组码和卷积码。分组码适用于一连串固定长度的数据包,而每一种分组码只能用于特定长度的数据包。实际用途中的分组码一般使用硬解码方式,所需时间为每一个数据包长度的多项式时间。经典分组码的其他例子有格雷码,BCH 码,多维奇偶校验码和汉明码。 卷积码适用于任意长度的位元流/符号流。接收方通常使用维特比算法将其软解码,但有时也会用其他算法。随着卷积码约束条件的长度增加,维特比解码的解码效率渐近最优;但作为代价,计算时间将以对数式增长。长度有限的卷积码也可以看作一种“分组码”,因为输入数据是成组的;但是卷积码的每一“组”长度不一,而分组码的长度是固定的,且由其特定的代数性质而定。

2.2 里德-所罗门码

本文介绍的 Par 2.0 使用的纠错码为里德-所罗门码,被广泛的应用各个领域,它是一种分组码。

里德-所罗门码是 RAID 6 的标准之一,常见的二维码中的 QR 码也采用它进行纠错,也被广泛运用在 CD、DVD、蓝光光盘的校验恢复上。

具体实现过程不在此叙述,可以问问万能的搜索引擎,看看维基百科上的词条或者百度百科上的词条

3. 创建纠错数据和恢复文件

可以实现的工具有很多,从软件维护情况、是否开源、免费等方面考虑,本文推荐的是 命令行工具 par2cmdline 和带图形界面的 MultiPar,同时考虑到 WinRAR 的受众广泛,会在附中给出 WinRAR 的实现方案。

本次测试使用文件:

  • 一个 PDF 文件,大小 42384523 字节(约 40.4 MB)
  • 一个文本 TXT 文件,大小 24286 字节(约 27 KB)

需要注意:随着被处理文件的大小增大,所需的计算时间也会更长。

3.1 使用 Par2cmdline 创建恢复模块和恢复数据

推荐查看:par2cmdline 在 Github 上的页面,有完整的命令行说明。

par2cmdline 的快速帮助(可以通过 par2 -h 进行查看)

Usage:
  par2 -h  : show this help
  par2 -V  : show version
  par2 -VV : show version and copyright

  par2 c(reate) [options] <PAR2 file> [files] : Create PAR2 files
  par2 v(erify) [options] <PAR2 file> [files] : Verify files using PAR2 file
  par2 r(epair) [options] <PAR2 file> [files] : Repair files using PAR2 files

You may also leave out the "c", "v", and "r" commands by using "par2create",
"par2verify", or "par2repair" instead.

Options: (all uses)
  -B<path> : Set the basepath to use as reference for the datafiles
  -v [-v]  : Be more verbose
  -q [-q]  : Be more quiet (-q -q gives silence)
  -m<n>    : Memory (in MB) to use
  -t<n>    : Number of threads used for main processing (6 detected)
  -T<n>    : Number of files hashed in parallel
             (2 are the default)
  --       : Treat all following arguments as filenames
Options: (verify or repair)
  -p       : Purge backup files and par files on successful recovery or
             when no recovery is needed
  -N       : Data skipping (find badly mispositioned data blocks)
  -S<n>    : Skip leaway (distance +/- from expected block position)
Options: (create)
  -a<file> : Set the main PAR2 archive name
  -b<n>    : Set the Block-Count
  -s<n>    : Set the Block-Size (don't use both -b and -s)
  -r<n>    : Level of redundancy (%%)
  -r<c><n> : Redundancy target size, <c>=g(iga),m(ega),k(ilo) bytes
  -c<n>    : Recovery Block-Count (don't use both -r and -c)
  -f<n>    : First Recovery-Block-Number
  -u       : Uniform recovery file sizes
  -l       : Limit size of recovery files (don't use both -u and -l)
  -n<n>    : Number of recovery files (don't use both -n and -l)
  -R       : Recurse into subdirectories

Example:
   par2 repair *.par2

3.1.1 创建恢复数据

最简单的可以直接根据默认参数进行创建:

./par2 create demo.pdf.par2 demo.pdf
# Block size: 21196
# Source file count: 1
# Source block count: 2000
# Recovery block count: 100
# Recovery file count: 7
# 
# Opening: demo.pdf
# Computing Reed Solomon matrix.
# Constructing: done.
# Wrote 2119600 bytes to disk
# Writing recovery packets
# Writing verification packets
# Done

即可获得恢复文件:

demo.pdf 和创建好的 par 文件

根据其帮助的用法,使用 -r 可以指定恢复数据的大小(百分比或固定大小),使用 -b 可以设置恢复块数量,使用 -s 可以设置恢复块大小,需要注意 -s 给出的参数需能被 4 整除。

-s 参数的例子:

par2 create -s24288 demo.txt.par2 demo.txt

-r、-b 参数的例子:

# 创建文件大小的 15% 恢复数据
par2 create -b v10240 -r15% demo.pdf.par2 demo.pdf

# 创建约 4 M 大小的恢复数据
par2 create -rm4 demo.pdf.par2 demo.pdf

恢复按块进行恢复,恢复数据的大小由块的数量和大小决定(所以不可以同时设置块的数量和块的大小),同样大小的恢复数据,不同参数和不同损坏情况是否能恢复可能产生不同的结果,所以针对可能出现的不同的文件损坏情况合理设置参数很重要。

3.1.2 进行文件修复

可以通过 par -v 文件名 来对文件进行校验,如:

par2 v demo.pdf.par2

得到输出:

Loading "demo.pdf.par2".
Loaded 4 new packets
Loading "demo.pdf.vol000+01.par2".
Loaded 1 new packets including 1 recovery blocks
Loading "demo.pdf.vol001+02.par2".
Loaded 2 new packets including 2 recovery blocks
Loading "demo.pdf.vol003+04.par2".
Loaded 4 new packets including 4 recovery blocks
Loading "demo.pdf.vol007+08.par2".
Loaded 8 new packets including 8 recovery blocks
Loading "demo.pdf.vol015+16.par2".
Loaded 16 new packets including 16 recovery blocks
Loading "demo.pdf.vol031+32.par2".
Loaded 32 new packets including 32 recovery blocks
Loading "demo.pdf.vol063+64.par2".
Loaded 64 new packets including 64 recovery blocks
Loading "demo.pdf.vol127+54.par2".
Loaded 54 new packets including 54 recovery blocks
Loading "demo.pdf.par2".
No new packets found

There are 1 recoverable files and 0 other files.
The block size used was 21196 bytes.
There are a total of 2000 data blocks.
The total size of the data files is 42384523 bytes.

Verifying source files:

Opening: "demo.pdf"
Target: "demo.pdf" - found.

All files are correct, repair is not required.

表明文件未损坏,对文件使用十六进制编辑器进行随机修改,来模拟文件损坏情况,再执行 par -v 可得到如下输出:

# ...
Verifying source files:

Opening: "demo.pdf"
Target: "demo.pdf" - damaged. Found 1999 of 2000 data blocks.

Scanning extra files:


Repair is required.
1 file(s) exist but are damaged.
You have 1999 out of 2000 data blocks available.
You have 181 recovery blocks available.
Repair is possible.
You have an excess of 180 recovery blocks.
1 recovery blocks will be used to repair.

表明文件可以被修复:

par2 r demo.pdf.par2

部分输出内容:

Computing Reed Solomon matrix.
Constructing: done.
Solving: done.

Wrote 42384523 bytes to disk

Verifying repaired files:

Opening: "demo.pdf"
Target: "demo.pdf" - found.

Repair complete.

修复成功。

若文件损坏过于严重或恢复块数据不足则无法恢复文件,这里给出对 demo.pdf 仅设置 1 个恢复块但损坏出现在了不同的两块中的情况则无法进行恢复,执行验证或恢复指令会得到如下输出:

Verifying source files:

Opening: "demo.pdf"
Target: "demo.pdf" - damaged. Found 1998 of 2000 data blocks.

Scanning extra files:


Repair is required.
1 file(s) exist but are damaged.
You have 1998 out of 2000 data blocks available.
You have 1 recovery blocks available.
Repair is not possible.
You need 1 more recovery blocks to be able to repair.

3.2 使用 MultiPar 创建恢复模块和恢复数据

可以看看:MultiPar 在 Github 上的页面

MultiPar 的整体思路和参数含义和 par2cmdline 相似,GUI 的操作会更便捷。

在 MultiPar 的文档中看到作者为了获得更高速度所做的努力,其描述:

Pros: Fast verification. Fast recovery. Less disk space. Cons: Backup of damaged files is disabled. Less finding available source blocks. Cannot treat splited source files. Cannot treat additional source files. Cannot treat external source files. Risk of more data loss at failed recovery.

3.2.1 创建恢复数据

提示:警惕恶意软件,建议前往 Github 的 Release 页面进行 下载。

通过 GUI 设置参数,进行操作即可:

创建恢复数据
创建成功

验证数据:

未损坏的文件校验结果

3.2.2 恢复数据

打开MultiPar,点击打开,选择 par2 文件进行校验

损坏数据的校验结果
修复成功
恢复块不足,无法恢复

使用 WinRAR 创建恢复模块和恢复数据

注:只有 RAR 格式可进行恢复卷设置。

在创建压缩包时勾选添加恢复记录,并设置恢复数据大小:

恢复记录
设置恢复记录大小

在文件损坏的压缩包内点击修复压缩文件:

修复压缩文件

按提示进行操作,修复结果:

修复成功