Skip to main content

通过冗余纠错码和哈希审计帮助文件固定(数据的长期存储)。

项目描述

构建状态 覆盖状态 PyPi 状态 皮皮下载

本项目旨在提供一套开源、跨平台、易于使用且易于维护的(可读代码)来保护和管理长期存储的数据。该项目是在纯 Python 中完成的,以满足这些标准。

这是 pyFileFixity 可以做的一个例子:

图像损坏和修复示例

在左边,这是原始图像。

在中心,相同的图像但有一些符号损坏(标题中只有 3 个,文件的其余部分中只有 2 个,这等于总共损坏了 5 个字节,超过 19KB,这是总文件大小)。只有几个损坏的字节就足以使图像看起来完全无法恢复,但我们很幸运,因为如果任何“魔术字节”被损坏,图像可能根本无法读取!

在右侧,损坏的图像是使用pyFileFixity的 header_ecc.py 修复的。这仅修复了图像头(即文件的第一部分),因此仅修复了前 3 个损坏的字节,而不是文件其余部分的 2 个字节,但我们可以看到图像看起来完全修复了!最棒的是,它只花费了“ecc修复文件”的生成,大小只有3.3KB(原始文件的17%)!

这是因为大多数文件将存储最重要的信息以在开始时读取它们,也称为“文件头”,因此修复这部分几乎总是可以确保读取文件的可能性(即使文件的其余部分仍然损坏,如果标题是安全的,你可以阅读它)。

当然,您也可以使用 pyFileFixity 的 structure_adaptive_ecc.py来保护整个文件,而不仅仅是文件头。您还可以使用rfigc.py检测任何损坏。


<nav class="contents" id="table-of-contents" role="doc-toc">

目录

</nav>

快速开始

在 Python 2.7.10 和 PyPy 上运行(尚未移植到 Python 3,但库已经兼容)。

  • 生成监控数据库(稍后检查文件是否被更改,但无法修复):

python rfigc.py -i "your_folder" -d "dbhash.csv" -g -f -l "log.txt"

注意:这也适用于单个文件,只需将“your_folder”替换为“your_file.ext”。

  • 检查文件是否损坏:

python rfigc.py -i "your_folder" -d "dbhash.csv" -l log.txt -s -e errors.csv

  • 要在文件抓取后使用此监控数据库恢复文件名和目录布局:

python rfigc.py -i "your_folder" -d "dbhash.csv" -l "log.txt" -o "output_folder" --filescraping_recovery

  • 要使用名为hecc.txt的文件保护文件头:

python header_ecc.py -i "your_folder" -d "hecc.txt" -l "log.txt" -g -f --ecc_algo 3

  • 要修复文件头并将修复的文件存储在output_folder中:

python header_ecc.py -i "your_folder" -d "hecc.txt" -o "output_folder" -l "log.txt" -c -v --ecc_algo 3

  • 要使用名为ecc.txt的文件保护整个文件:

python structure_adaptive_ecc.py -i "your_folder" -d "ecc.txt" -l "log.txt" -g -f -v --ecc_algo 3

  • 要修复整个文件:

python structure_adaptive_ecc.py -i "your_folder" -d "ecc.txt" -o "output_folder" -l "log.txt" -c -v --ecc_algo 3

  • 使用索引文件ecc.txt.idx修复 ecc 文件ecc.txt(索引文件是使用 ecc.txt 自动生成的):

python repair_ecc.py -i "ecc.txt" --index "ecc.txt.idx" -o "ecc_repaired.txt" -l "log.txt" -v -f

  • 要修复没有索引文件的 ecc 文件ecc.txt (您可以将-t参数从 0.0 调整到 1.0,1.0 会产生许多误报):

python repair_ecc.py -i "ecc.txt" -o "ecc_repaired.txt" -l "log.txt" -v -f -t 0.4

  • 要使用存储在不同介质上的多个副本修复文件:

replication_repair.py -i "path/to/dir1" "path/to/dir2" "path/to/dir3" -o "path/to/output" --report "rlog.csv" -f -v

  • 如果您之前生成了 rfigc 数据库,则可以使用它来增强复制修复:

replication_repair.py -i "path/to/dir1" "path/to/dir2" "path/to/dir3" -o "path/to/output" -d "dbhash.csv" --report "rlog.csv" -f -v

  • 要在您的恢复工具上运行测试,您可以制作一个类似于 Makefile 的配置文件并使用:

resiliency_tester.py -i "your_folder" -o "test_folder" -c "resiliency_tester_config.txt" -m 3 -l "testlog.txt" -f

  • 要获得任何工具的更多选项,请使用--help

  • 要将 GUI 与任何工具一起使用,请使用--gui并且不要提供任何其他参数,例如:python rfigc.py --gui

  • 您还可以在这里使用PyPy极大地加快任何工具的处理时间。

长期存放问题

为什么数据会随着时间而损坏?熵,我的朋友,熵。熵是指系统随着时间的推移变得不那么有序的普遍趋势。腐败就是这样:比特顺序的混乱。换句话说:宇宙讨厌你的数据

因此,长期存储是一个非常困难的话题:就像与死亡作斗争(在这种情况下,是数据的死亡)。确实,由于熵的原因,数据最终会因为比特腐烂等各种无声错误而消失。pyFileFixity 旨在提供检测任何数据损坏的工具,同时通过提供修复工具来对抗数据损坏。

唯一的解决方案是使用一个众所周知的工程原理并使桥梁安全:添加一些冗余

只有 2 种方法可以添加冗余:

  • 添加冗余的简单方法是复制对象(也称为复制),但是对于数据存储,这会占用大量存储空间并且不是最优的。

  • 第二种方法,也是迄今为止发明的从数据损坏中恢复的最佳、最佳工具,是纠错码(前向纠错),这是一种从数据中巧妙地生成冗余码的方法,以便您以后可以使用以下方法修复数据这些额外的信息(即,ECC 为被切割成 k 个块(k < n)的文件生成 n 个块,然后 ecc 代码可以用(至少)总 n 个块中的任何 k 个块重建整个文件可用的)。换句话说,您最多可以纠正 (nk) 个擦除。但是纠错码也可以自动检测和修复错误所在的位置(全自动数据修复!),但代价是您只能纠正 (nk)/2 个错误。

纠错似乎有点神奇,但出于合理的直觉,它可以看作是一种平均损坏错误率的方法:平均而言,一个位仍然有相同的机会被损坏,但是由于你有更多的位要代表相同的数据,您会降低丢失此位的总体机会。

问题在于,大多数关于纠错码的理论和实践工作几乎只针对信道传输(例如 4G、互联网等),而不是数据存储,这有很大不同,原因有一个:而在信道中我们处于空间方案中(发送者和接收者都是空间中的不同实体,但在相同的时间尺度上工作),在数据存储中这是一个时间方案:发送者是您在时间 t 将数据存储在您的介质上,并且接收者又是你,但现在在时间 t+x 检索数据。因此,发送方不再存在,因此如果数据损坏太多,您不能要求发送方再次发送一些数据:在数据存储中,如果数据损坏,它会永远丢失,而在通道理论中,部分数据必要时可以再次提交。

一些尝试将通道理论和纠错码理论转化为数据存储,第一个是产生 RAID 模式的 Reed-Solomon。然后,CIRC(交叉交错 Reed-Solomon 编码)被设计用于光盘上以从划痕中恢复,这是该技术可供消费者使用的必要条件。从那时起,人们发明了(或重新发现)新的不太优化但速度更快的算法,例如 LDPC、turbo 码和喷泉码(例如 RaptorQ),但它们在数据存储方面的研究仍然很少。

该项目旨在首先实现评估策略(filetamper.py)和文件固定性(即检测是否存在损坏)的简单工具,然后目标是提供一个开放且简单的框架来使用不同类型的纠错保护和修复文件的代码。

此外,ecc 文件规范非常简单且可抵御损坏,因此您可以根据需要自行处理它,而无需花费数小时研究代码的工作原理(与 PAR2 格式相反)。

为什么不只使用 RAID?

RAID 显然不足以用于长期数据存储,事实上,它主要是作为一种获得更多存储 (RAID0) 或更多数据可用性 (RAID1) 的廉价方式,而不是用于归档数据,即使在中等时间范围内也是如此:

  • RAID 0 只是像使用单个磁盘一样使用多个磁盘来扩展可用存储。让我们跳过这个。

  • RAID 1 将一个磁盘与另一个磁盘的逐位副本进行镜像。这对于长期存储来说完全没有用:如果任一磁盘出现故障,或者两个磁盘都部分损坏,您将无法知道哪些数据是正确的,哪些不是。古语有云:“不要拿2个罗盘:要么拿3个,要么拿1个,因为如果两个罗盘指向不同的方向,你永远不知道哪个是正确的,也不知道两者都错了。” 这就是三重原理。

  • RAID 5 基于三重复制思想:您有 n 个磁盘(但至少有 3 个),如果一个磁盘发生故障,您可以恢复 n-1 个磁盘(仅可恢复 1 个磁盘故障,而不是更多)。

  • RAID 6 是 RAID 5 的扩展,它更接近错误纠正,因为您可以纠正 nk 磁盘。但是,大多数(全部?)目前市售的 RAID6 设备最多只能实现 n-2(2 个磁盘故障)的恢复。

  • 在任何情况下,RAID 都无法自动检测静默错误,因此您要么必须定期扫描,要么冒着永久丢失一些数据的风险,而且它比您预期的要普遍得多(例如,使用 RAID5,拥有同一位上的两个磁盘上出现 2 个静默错误,导致该位不可恢复)。这就是为什么仅限制 1 或 2 个磁盘故障是不够的。

相反,ECC 可以更正 nk 个磁盘(或文件)。您可以根据需要配置 n 和 k,例如,您可以设置 k = n/2,这意味着您只能从其中一半中恢复所有文件!(当然,一旦它们用 ecc 文件编码)。

还有新一代 RAID 解决方案,主要是基于软件的,例如 SnapRAID 或 ZFS,它们允许您配置具有所需值 nk 的虚拟 RAID。这就像一个 ecc 文件(但不太灵活,因为它不是文件而是磁盘映射,因此您不能只是将其复制或上传到云备份主机)。除了恢复 (nk) 磁盘之外,它们还可以配置为从磁盘内部的部分扇区故障中恢复,而不仅仅是整个磁盘(有关更详细的说明,请参阅 Plank、James S.、Mario Blaum 和 James L . Hafner. “SD 代码:为存储系统如何真正发生故障而设计的擦除代码。”FAST。2013 年。)。

RAID 不适合长期存储的另一个原因是,它假设您将数据专门存储在硬盘驱动器上。从长远来看,硬盘不是一个好的存储介质,原因有两个:

1-他们需要一个常规插头来保持内部磁盘通电(否则当没有剩余电力时数据会消失)。
2-读数仪直接包含并与数据合并(这是你从外面看到的绿色电子板,内部头部)。这对消费者快速使用有好处(不需要购买其他仪器:只需插入硬盘即可使用),但对于长期存储非常不利,因为读取仪器肯定会失败,而且速度要快得多比数据可以消失:这意味着即使您的硬盘驱动器内的磁盘仍然保存您的数据,如果控制器板或磁头不再工作,您的数据就会丢失。而且磁头(和控制器板)几乎不可能更换,即使是专业人士也是如此,因为这些部件很难找到(每条 HDD 生产线都不同)并且每个 HDD 都有一些小的物理缺陷,

最后,还是把数据的存储介质和读取仪器分开就好多了。我建议的介质是光盘(无论是蓝光、DVD、CD 还是其他),因为读取仪器是独立的,而且技术(激光反射在凹凸和/或凹坑上)是通用的,所以即使技术有一天会丢失(被新技术弃用,因此您再也找不到读取仪器了,因为它不再出售了),您可能可以使用一些软件模拟激光读取您的光盘,就像 CAMiLEON 项目所做的那样从 BBC Domesday Project 的 LaserDiscs 中恢复数据(参见 Wikipedia)。

包括的应用程序

该项目目前包括以下纯 python 应用程序:

  • rfigc.py,一个类似于 md5deep/hashdeep 的哈希审计工具,用于计算文件及其元数据的数据库,以便稍后您可以检查它们是否被更改/损坏。

  • header_ecc.py,一个使用 Reed-Solomon 生成器/校正器来处理文件头的错误校正代码。这个想法是补充其他更常见的冗余工具,例如 PAR2(非常可靠),仅在文件的关键部分(它们的标题)上添加更多弹性。使用此脚本,您可以显着提高恢复标头的机会,这将允许您至少打开文件。

  • structure_adaptive_ecc.py,可变纠错率编码器(header_ecc.py 的一种概括)。该脚本允许为文件的全部内容生成一个 ecc 文件,而不仅仅是标题部分,使用可变的恢复率:标题部分将是最受保护的,然后每个文件的其余部分将逐渐编码为更小的和较小的回弹率。假设是首先存储重要信息,然后数据变得越来越少(因此很重要,因为文件末尾描述了不太重要的细节)。这个假设对于所有压缩类型的格式都非常正确,例如 JPG、ZIP、Word、ODT 等……

  • repair_ecc.py,一个脚本,用于修复由 header_ecc.py 或structure_adaptive_ecc.py 生成的 ecc 文件的结构(即条目和字段标记/分隔符)。目标是通过确保可以修复它们的结构来增强 ecc 文件对损坏的恢复能力(如果您使用索引备份文件,它是一个随 ecc 文件生成的伴随文件,直到某个点非常高)。

  • filetamper.py 是一个快速制作的文件损坏器,它会擦除​​或更改指定文件中的字符。这对于测试您的各种保护策略和文件格式很有用(例如:PAR2 真的可以抵御损坏吗?zip 存档在损坏后是否仍然可以部分提取,或者 rar 存档更好吗?等等)。不要低估此工具的实用性,因为您应该始终检查文件格式和文件保护策略的弹性,然后再依赖它们。

  • easy_profiler.py 只是一个快速简单的分析工具,可让您快速开始应该优化什么以获得更快的速度,如果您想为项目做出贡献,请随时提出拉取请求!(欢迎 Cython 和其他优化,只要它们是跨平台的,并且还可以使用替代的纯 python 实现)。

  • replication_repair.py 利用您在多个存储介质上的多个数据副本(复制)来恢复您的数据,以防数据损坏。目标是利用存档文件存储到多个位置的优势:您必须进行复制,那么为什么不使用它们进行修复呢?确实,在多个存储介质上保留多个相同的数据副本是一种很好的做法,但如果发生损坏,通常您只需删除损坏的副本并保留完整的副本。但是,如果所有副本都部分损坏,那么您将陷入困境。该脚本旨在利用这些多个副本来恢复您的数据,而无需生成先前的 ecc 文件。它只需通过读取所有不同的数据副本即可工作,并且对每个字节进行多数投票:将保留最常出现的那个。在工程中,这是一种非常常见的策略,用于非常可靠的系统,如太空火箭,被称为“三模块冗余”,因为您需要至少 3 个数据副本才能让多数人投票工作(但越多更好的)。

  • resiliency_tester.py 允许您测试此处提供的脚本(或任何其他命令行应用程序)的损坏校正的稳健性。您只需要将要测试的文件复制到文件夹中,然后脚本会将文件复制到测试树中,然后它会自动随机破坏文件(您可以更改块突发等参数),然后它将运行您提供的文件修复命令行,最后将生成一些有关修复能力的统计信息。这使您可以轻松客观地比较不同的参数集,甚至是不同的文件修复解决方案,对您而言非常重要的数据,以便您可以选择最适合您的选项。

请注意,所有工具主要用于命令行(键入 script.py –help 以获取有关已接受参数的扩展信息),但您也可以通过使用 –gui 参数在 GUI 中使用 rfigc.py 和 header_ecc.py (必须是提供的第一个也是唯一一个参数)。GUI 是按原样提供的,维护它只需做最少的工作(重点将放在功能上,而不是人体工程学上)。

重要提示:使用与生成数据库/ecc 文件时相同的参数来纠正模式是至关重要的(对于此捆绑包中的所有脚本都是如此)。当然,某些选项必须更改:-g 必须变为 -c 才能更正,而--update 是一个特例。这样做的目的主要有两个原因:首先,因为很难单独从数据库文件中自动检测参数,并且会产生大量误报,其次(主要原因)是将参数存储在数据库文件中对损坏高度无弹性(如果数据库的这一部分被篡改,则整体变得不可读,而如果它们存储在外部或您自己的内存中,则始终可以访问数据库文件)。因此,建议将您用于生成数据库的参数直接写在您将存储数据库文件的存储介质上(例如:如果是光盘,请将参数写在封面上或使用标记直接写在磁盘上) ,或者更好地记住它们。如果您忘记了它们,请不要惊慌,参数始终作为注释存储在生成的 ecc 文件的标题中,但无论如何您都应该尝试将它们存储在 ecc 文件之外。

对于用户:pyFileFixity 的优势是什么?

优点:

  • 在 MIT 许可下开放应用程序和开放规范(您可以随心所欲地使用它并根据需要对其进行定制,或者随着科学的进步在未来添加更好的解码程序,以便您可以更好地从您的已生成 ecc 文件)。

  • 高度可靠的文件修复观察器:rfigc.py 将使用多个属性毫不含糊地告诉您文件是否已损坏,甚至可以检查文件头是否有效(即:文件是否仍可打开)。

  • 可读的 ecc 文件格式(与 PAR2 和大多数其他类似规范相比)。

  • 具有高度弹性的 ecc 文件格式以防止损坏(不仅您的数据受 ecc 保护,ecc 文件也受到保护免受关键点的影响,因为没有标题,因此每个轨道都是独立的,如果一个轨道损坏无法修复,那么其他 ecc仍然可以读取磁道,并且会生成一个 .idx 文件来修复 ecc 文件的结构以恢复所有磁道)。

  • 非常安全和保守的方法:恢复过程在提交修复的块之前检查恢复是否成功。

  • 允许部分恢复(即使文件不能完全恢复,可以修复的部分将被修复,然后将无法修复的部分从损坏的版本中重新复制)。

  • 支持目录处理:您可以为整个文件目录(具有任意数量的子目录和深度)编码一个 ecc 文件。

  • 文件数量没有限制,可以递归保护目录树中的文件。

  • 可变弹性率和仅头文件弹性,确保即使部分损坏,您也可以始终打开文件(文件结构将被保存,以便您可以使用其他软件修复,如果这组脚本不足以修复完全修复)。

  • 支持擦除(空字节)甚至错误和擦除,这实际上使修复能力加倍。据我所知,这是唯一一款支持擦除的免费奇偶校验软件。

  • 显示给定参数的预测总 ecc 文件大小,以及编码/解码所需的总时间。

  • 不需要外部库,只需要本机 Python 2.7.x(但使用 PyPy 会更快!)。

  • 在非常宽松的 MIT 许可下开源,随心所欲!

缺点:

  • 无法保护元数据,例如文件夹路径。路径已存储,但无法恢复(还没有?如果您知道如何做,请随时贡献)。只有文件受到保护。因此,如果您的操作系统或存储介质崩溃并截断整个目录树,则无法使用 ecc 文件修复目录树,因此您也无法访问这些文件。但是,即使目录树丢失,您也可以使用文件抓取来提取文件,然后使用 RFIGC.py 正确重组文件。还有其他选择,请参阅以下章节:您可以使用 DAR 或 ZIP 将所有文件打包在一个存档中(因此 ecc 也将保护元数据),或者将 DVDisaster 作为替代解决方案,它是一个 ecc 生成器支持目录树元数据(但仅在光盘上)。

  • 只能修复错误和擦除(被另一个字符替换的字符),不能删除或插入字符。但是,这不应该发生在任何存储介质上(如果错误检测到文件边界,可能会发生截断,在这种情况下,pyFileFixity 可以部分修复文件的已知部分,但无法恢复截断后的其余部分,除非您使用了弹性率至少为 0.5,在这种情况下,任何消息块都可以仅使用 ecc 文件重新创建)。

  • 与 Parchives (PAR1/PAR2) 不同,无法从其他可用文件重新创建丢失的文件(除非您已将弹性速率设置为至少 0.5)。因此,只有当您的文件系统上仍有文件时,您才能修复该文件。如果它丢失,pyFileFixity 不能做任何事情(但是,这将在未来实现)。

请注意,这些工具用于数据存档(保护您将不再修改的文件),而不是用于系统文件监视或保护计算机上的所有文件。为此,您可以使用直接集成纠错码能力的文件系统,例如 ZFS。

Python 中的递归/相对文件完整性生成器和检查器(又名 RFIGC)

通过 MD5 和 SHA1 哈希、大小、修改日期或数据结构完整性(仅适用于图像)递归生成或检查文件的完整性。

该脚本最初旨在用于数据存档,通过一种简单的方法来检查静默文件损坏。因此,此脚本使用相对路径,以便您可以轻松计算和检查复制到不同介质(硬盘驱动器、光盘等)上的相同冗余数据。这个脚本不是用于系统文件损坏通知,而是更多地用于不时地检查您的数据存档完整性(如果您需要这种应用程序,请参阅avpreserve 的 fixity)。

这个脚本是为 Python 2.7.6 制作的,但它应该很容易适应在 Python 3.x 上运行。

示例用法

  • 生成数据库(只需要一次):

python rfigc.py -i "your_folder" -d "dbhash.csv" -g

  • 去检查:

python rfigc.py -i "your_folder" -d "dbhash.csv" -l log.txt -s

  • 通过附加新文件来更新数据库:

python rfigc.py -i "your_folder" -d "dbhash.csv" -u -a

  • 通过添加新文件和删除不存在的文件来更新数据库:

python rfigc.py -i "your_folder" -d "dbhash.csv" -u -a -r

请注意,默认情况下,脚本默认处于检查模式,以避免错误操作。如果您在已经存在的数据库文件上生成,它也会提醒您。

论据

  -h, --help            show a help message and exit
  -i /path/to/root/folder, --input /path/to/root/folder
                        Path to the root folder from where the scanning will occ
ur.
  -d /some/folder/databasefile.csv, --database /some/folder/databasefile.csv
                        Path to the csv file containing the hash informations.
  -l /some/folder/filename.log, --log /some/folder/filename.log
                        Path to the log file. (Output will be piped to both the
stdout and the log file)
  -s, --structure_check
                        Check images structures for corruption?
  -e /some/folder/errorsfile.csv, --errors_file /some/folder/errorsfile.csv
                        Path to the error file, where errors at checking will be
 stored in CSV for further processing by other softwares (such as file repair so
ftwares).
  -m, --disable_modification_date_checking
                        Disable modification date checking.
  --skip_missing        Skip missing files when checking (useful if you split yo
ur files into several mediums, for example on optical discs with limited capacit
y).
  -g, --generate        Generate the database? (omit this parameter to check ins
tead of generating).
  -f, --force           Force overwriting the database file even if it already e
xists (if --generate).
  -u, --update          Update database (you must also specify --append or --rem
ove).
  -a, --append          Append new files (if --update).
  -r, --remove          Remove missing files (if --update).

  --filescraping_recovery          Given a folder of unorganized files, compare to the database and restore the filename and directory structure into the output folder.
  -o, --output          Path to the output folder where to output the files reorganized after --recover_from_filescraping.

标头纠错码脚本

该脚本被设计为与其他更常见的文件冗余生成器(例如 PAR2,我建议 MultiPar)结合使用。这是对文件的额外保护层:通过在文件头上使用更高的弹性率,您可以确保将来可能能够打开它们,避免“关键点”,也称为“断裂” -critical”在冗余工程中(如果你只修改一个位,你的整个文件可能变得不可读,通常是位于标题中的位 - 换句话说,一次打击会使整个事情崩溃,就像非冗余桥一样)。

这种方法的一个有趣的好处是它具有较低的存储(和计算)开销,无论文件大小如何,它都可以线性扩展:例如,如果我们有一组 40k 文件,总大小为 60 GB ,resilency_rate 为 30%,header_size 为 1KB(我们限制为前 1K 字节/字符 = 我们的文件头),那么,不计算每个块的哈希值和其他元数据,最终的 ECC 文件将约为 2 * resiliency_rate * number_of_files * header_size = 24.5 MB。如果有很多小于 1KB 的文件,这个大小可以更小。备份如此大量文件的标头的存储开销非常低。

该脚本是纯 python 及其依赖项:因此它是完全跨平台和开源的。但是,这意味着它很慢,但是 PyPy v2.5.0 没有任何修改就成功地针对脚本进行了测试,并且可以观察到速度增加了 100 倍以上,因此您可以预期超过 1MB/s 的速率,这是相当快的。

结构自适应纠错编码器

该脚本实现了一个可变纠错率编码器:每个文件使用可变弹性率进行 ecc 编码 - 对标头部分使用高恒定弹性率(弹性率阶段 1,高),然后将可变弹性率应用于其余部分文件内容的百分比,在文件开头附近具有较高的速率(弹性率阶段 2,中等)逐渐降低,直到文件结尾(弹性率阶段 3,最低)。

这个想法是文件的关键部分通常放在顶部,数据在文件中变得越来越不重要。关键的意思是关键点(例如:如果您仅篡改文件头的一个字符,您很有可能丢失整个文件,即您甚至无法打开它)和关键编码信息(例如:存档格式通常在文件中对压缩符号进行编码,这意味着第一次出现被编码,然后存档只是简单地写入对符号的引用。因此,第一次出现在顶部编码,随后对相同数据进行编码模式将只是一个符号,因此只要原始符号被正确编码并保留其信息,我们总是可以稍后尝试恢复参考符号)。而且,

这种可变的纠错率应该允许保护文件的更多关键部分(文件的标题和开头,例如压缩文件格式,如 zip 或 jpg,这是最重要的字符串编码的地方)相同存储量作为标准的恒定纠错率。

当然,您可以将每个阶段的弹性率设置为您想要的值,这样您甚至可以做相反的事情:为阶段 3 设置一个比阶段 2 更高的弹性率会在接近结束时产生更大的 ecc您的文件的内容。

此外,当前设计的 ecc 文件格式将允许在所有当前文件 ecc 生成器(例如 PAR2)中不可用的两件事:

1.它允许部分修复文件,即使不是所有的块都可以修复(在PAR2中,只有在所有块都可以修复的情况下才会修复文件,这是一种耻辱,因为还有其他块可以修复并且从而产生一个损坏较少的文件);

2. ecc 文件格式非常简单易读,很容易被任何脚本处理,这将允许其他软件也可以在它上面工作(而且它也是以这种方式完成的,以更好地抵御错误损坏,这样即使一个条目已损坏,其他条目是独立的并且可以使用,因此 ecc 非常容错。这个想法是在 repair_ecc.py 中实现的,但它可以扩展,特别是如果您知道损坏的模式)。

脚本structure-adaptive-ecc.py 实现了这个想法,它可以被看作是header-ecc.py 的扩展(实际上这个想法是相反的:structural-adaptive-ecc.py 是最先构想的,但是太复杂了,然后 header-ecc.py 被实现为仅适用于 headers 的工作简化实现,然后结构-adaptive-ecc.py 使用 header-ecc.py 代码进度完成)。它有效,它在数百 GB 的数据集上针对我自己的需求进行了很好的测试,但它并非万无一失,因此请确保您自己测试脚本以查看它是否足够强大以满足您的需求(对此的任何反馈都会非常有用赞赏!)。

ECC 算法

您可以使用--ecc_algo开关指定不同的 ecc 算法。

目前,仅实现了 Reed-Solomon,但它是通用的,因此您可以在 lib/eccman.py 中修改其参数。

有两个 Reed-Solomon 编解码器可用,它们在功能上是等效的并且经过了全面的单元测试。

  • --ecc_algo 1:在 fcr=1 的根 3 的 galois 字段 2^8 中使用第一个 Reed-Solomon 编解码器。这是最慢的实现(但也是最容易理解的代码)。

  • --ecc_algo 2:与算法 1 相同,但功能更快。

  • --ecc_algo 3:使用第二个编解码器,这是最快的。生成的 ECC 将与算法 1 和 2 兼容。

  • --ecc_algo 4:也使用第二个最快的 RS 编解码器,但参数不同(美国 FAA ADSB UAT RS FEC 规范),因此生成的 ECC 将与算法 1 到 3 不兼容。但不要害怕, ECC 将同样工作。

Cython 实施

本节介绍如何使用 Cython 实现。但是,您应该首先尝试 PyPy,因为在我们的案例中,它确实比 Cython 提供了 10 到 100 倍的加速。

包括 Reed-Solomon 库的快速 Cython 实现。它应该为所有脚本提供 C 速度(只要您使用 –ecc_algo 1 或 2,而不是 3 或 4)。它不是必需的,因为默认情况下使用纯 python 实现,但如果你想对数百 GB 的大数据集进行编码,它会很有用。

如果要构建 C/Cython 实现,请执行以下操作:

1-为您的平台安装 C 编译器。在 Linux 上,应该已经安装了 gcc。在 Windows 上,您需要使用 Visual Studio C 编译器(不是 MinGW 或 Cygwin gcc,它们不会工作)。您可以使用“Microsoft Visual C++ Compiler for Python 2.7”,如果您的 Python < 2.7.10,请按照以下说明使其工作:

https://github.com/cython/cython/wiki/CythonExtensionsOnWindows

2- cd 到这个文件夹(pyFileFixity 所在的位置),然后执行以下命令:

python setup.py build_ext --inplace --compiler=msvc

如果一切顺利,C 编译器将编译 .c 文件(由 Cython 预先生成),然后您可以像往常一样使用 PyFileFixity 脚本,您应该会看到巨大的加速。否则,如果它不起作用,您可能需要使用 Cython 为您的平台生成 .c 文件(因为预生成的 .c 文件可能与您的平台不兼容)。为此,您只需要安装 Cython,这对于如今的 Python 发行版(如 Anaconda)来说是一项简单的任务:下载 32 位 Anaconda 安装程序(在 Windows 上,您应该避免使用 64 位,它可能会在 Cython 中产生奇怪的问题),然后安装后,打开 Anaconda 命令提示符并执行:conda install cython。这将沿着 cython 库安装所有必要的东西。然后你可以简单地再次执行命令 python setup.py build_ext --inplace --compiler=msvc这一次它将从头开始重建,通过自动检测您是否安装了 Cython,setup.py 脚本将自动从 .pyx 文件和 .pyd 文件生成 .c 文件(二进制文件)来自 .c 文件。

如果遇到问题,可以查看以下有关如何安装 Cython 的帖子:

https://github.com/cython/cython/wiki/InstallingOnWindows

3- 您现在可以像往常一样启动 pyFileFixity,它应该会自动检测 C/Cython 编译文件并使用它来加速处理。

关于速度的注意事项:另外,使用较小的 –max_block_size 可以大大加快操作!这就是用于在光盘上快速计算 RS ECC 的技巧。你当然放弃了一点弹性(因为块更小,因此每个 ECC 保护的字符数量更少。最后,这对真正的弹性不会有太大的改变,但万一你得到一个大的比特错误突发一个连续的块,您可能会一次丢失整个块。这就是为什么使用 RS255 更好,但它非常耗时。但是,弹性比率仍然保持不变,因此对于任何其他具有平均大小突发的位翻转情况,这只要突发的大小小于一个 ecc 块,应该不是问题。)

如果发生灾难性事件

TODO:在这里写更多

如果由于存储介质故障(例如:您的硬盘驱动器崩溃)而导致您的数据发生灾难性事件,请按照以下步骤操作:

1- 使用 dd_rescue 在驱动器死机之前对其进行完整的逐位逐字复制。dd_rescue 的好处是副本是准确的,并且它可以在出现坏扇区的情况下重试或跳过(它不会在进程的一半时突然崩溃)。

2-使用testdisk恢复分区或根据分区文件系统信息复制文件。

3-如果您无法恢复您的文件,您可以尝试使用 photorec 或 plaso 其他类似工具进行文件抓取 作为 最后的手段,仅从文件内容中提取数据(没有文件名,通常不正确的文件类型,文件边界可能是错误的,所以一些数据可能会被切断等)。

4- 如果您在存储介质发生故障之前使用了 pyFileFixity,则可以使用预先计算的数据库检查文件是否完整(rfigc.py),如果不完整,您可以恢复它们(使用 header_ecc.py和结构自适应ecc.py)。如果您通过数据抓取恢复文件,它也会有所帮助,因为您的文件将完全杂乱无章,但您可以使用以前生成的数据库文件通过 rfigc.py –filescraping_recover 恢复全名和目录树结构。

此外,您可以尝试使用专门的修复工具修复您的一些文件(但请记住,此类工具不能保证您具有与纠错码相同的恢复能力 - 此外,纠错码可以告诉您何时成功恢复) . 例如:

保护目录树元数据

pyFileFixity 当前的一个主要限制是它不能保护目录树元数据。这意味着在最坏的情况下,如果指向您使用 ecc 保护的根目录的 inode 上发生无提示错误,则整个目录以及其中的所有文件都会消失。在不太糟糕的情况下,子目录可能会消失,但这仍然很糟糕,而且由于 ecc 文件不存储有关 inode 的任何信息,因此您无法恢复完整路径。

无法存储这些元数据是因为设计中有两个选择: 1- 可移植性:我们希望 ecc 文件能够工作,即使我们将根目录移动到另一个地方或另一个存储介质(当然,inode 会change), 2- 跨平台兼容性:没有办法获取和存储所有平台的目录元数据,但是我们当然可以针对每个主要平台实现特定的指令,所以这点不是问题。

为了解决这个问题(目录元数据是关键点),其他软件使用一次性存储介质(即,在生成和写入 ecc 的同时写入数据)。这样,他们可以在位级别访问 inode 信息,并保证 inode 永远不会改变。这是 DVDisaster 所采用的方法:通过使用光学介质,它可以计算永久的 inode,从而将这些信息编码到 ecc 文件中。另一种方法是创建一个虚拟文件系统,专门用于存储您的文件,以便您自己管理 inode,然后您可以复制整个文件系统(这实际上只是一个文件,就像一个 zip 文件 - 这也可以是实际上被认为是一个迷你虚拟文件系统),如 rsbep

这里 pyFileFixity 的可移植性原则阻止了这种方法。但是你可以在你的硬盘上模仿这个解决方法来让 pyFileFixity 工作:你只需要将所有文件打包到一个文件中。这样,您就可以创建一个虚拟文件系统:在存档内部,文件和目录具有元数据,就像在文件系统中一样,但从外部看,它只是一个文件,由我们可以编码以生成 ecc 的字节组成文件 - 换句话说,我们消除了 inode 可移植性问题,因为此元数据相对存储在存档中,存档管理它,我们可以像任何其他数据流一样编码此信息!从多个文件制作存档的常用方法是使用 TAR,但这会生成一个可靠的存档,从而防止部分恢复。另一种方法是使用 DAR,这是 TAR 的非固态存档版本,还具有许多其他功能。如果您还想压缩,您可以只使用 ZIP(使用 DEFLATE 算法)您的文件(这也会生成一个非实体存档)。然后,您可以使用 pyFileFixity 在您的 DAR 或 ZIP 存档中生成一个 ecc 文件,这将像以前一样保护您的文件和现在的目录元数据。

pyFileFixity 之类的工具(或可用作补充的工具)

以下是一些与 pyFileFixity 具有相似理念的工具,如果它们更适合您的需求,您可以使用它们,作为 pyFileFixity 的替代品或作为补充(pyFileFixity 始终可用于生成 ecc 文件):

  • DAR(磁盘存档):类似于 tar 但非固态,因此允许部分恢复和每个文件访问,此外它还保存目录树元数据 - 请参阅目录隔离 - 另外它可以使用 PAR2 和加密本机处理错误纠正。还支持增量备份,因此它是一个非常好的多功能工具。跨平台和开源。

  • DVDisaster:光学介质(CD、DVD 和 BD/蓝光光盘)的比特级纠错。非常好,它还可以保护目录树元数据,并且可以抵御损坏(v2 仍然有一些关键点,但 v3 不会有任何关键点)。

  • rsbep 工具是 Debian 中 dvbackup 软件包的一部分:允许生成字节流的 ecc。如果您使用的是 unix 或使用 cygwin,则非常适合通过管道传输到 dar 和/或 gz 进行备份。

  • Thanassis Tsiodras 的 rsbep 修改:增强 rsbep 以避免关键点和更快的速度。还包括一个“冻结”脚本,用于将文件编码为虚拟文件系统(使用 Python/FUSE),这样即使是目录树等元数据也受到 ecc 的完全保护。很棒的脚本,但没有维护,它需要由知识渊博的人进行一些密集的测试,以保证这个脚本对于生产来说足够可靠。

  • Parchive (PAR1, PAR2, MultiPar):众所周知的纠错文件生成器。Parchives 的一大优势是一个 ecc 块依赖于多个文件:这允许使用仍然可用的文件从头开始完全重建丢失的文件。对大多数人来说效果很好,但大多数可用的 Parchive 生成​​器对我来说并不满意,因为 1- 它们不允许递归地为目录树生成 ecc(MultiPar 除外,即使它在 PAR2 规范中是允许的),2-它们的生成速度可能非常慢(即使使用多处理器扩展,因为 galois 字段超过 2^16 而不是 2^8,这非常昂贵),3- 规范对错误和篡改 ecc 文件的弹性不是很好,因为它假设 ecc 文件不会被损坏(我也测试过,它仍然有点弹性,

  • Zip(使用 DEFLATE 算法,使用 7-Zip 或其他工具):允许创建大多数计算机都可以读取的非实体存档(普遍存在的算法)。非固态存档意味着即使文件损坏,zip 文件仍然可以解压缩正确的文件,因为文件是按块编码的,因此即使某些块损坏,也可能会发生解码。在纯 Go 中可以使用增强压缩的快速实现 (适合长时间存储)。

  • TestDisk:用于文件抓取,当没有其他方法时。

  • dd_rescue:用于磁盘抓取(允许在位级别强制读取整个磁盘并复制它可以复制的所有内容,传递坏扇区以及在第一次完全通过正确扇区后稍后重试它们的选项)。

  • ZFS:直接包含ecc修正的文件系统。整个文件系统,包括目录树元数据,都受到保护。如果您想在您的计算机上为您的所有文件提供 ecc 保护,这就是您要走的路。

  • 加密:从技术上讲,您可以在不丢失太多冗余的情况下加密文件,只要您使用基于块的加密方案,例如 DES:如果一个块被损坏,它将无法解密,但其余的文件的加密块应该可以毫无问题地解密。因此,使用此类算法进行加密会导致与非固态存档(例如 deflate zip)类似的文件。当然,对于非常长期的存储,最好避免加密和压缩(因为你提高了单个数据块中包含的信息,因此如果你丢失一个块,你会丢失更多数据),但如果你真的有必要,您仍然可以通过使用基于块的加密/压缩来保持恢复文件的高机会(注意:基于块的加密可以看作是用于压缩的非固态存档的等价物,

  • 快照RAID

  • par2ools:一组用于管理 par2 档案的附加工具

  • Checkm:类似于 rfigc.py 的工具

  • BagIt在这里这里有两个 python 实现:这是一种文件打包格式,用于共享和存储档案以供长期保存,它只是形式化了一些通常添加到文件中以进行长期存档的常用程序和元数据(例如 MD5 摘要)。

  • RSArmor一个基于 Reed-Solomon 的工具,用于将二进制数据文件编码为十六进制,以便您可以在纸上打印字符。对于小型数据集(小于 100 MB)可能很有趣。

  • Ent一个工具来分析你的文件的熵。优化纠错算法或压缩工具可能非常有趣。

  • HashFS是 Python 中的非冗余、无重复文件系统。重复数据删除对于大规模长期存储非常重要:由于您希望数据是冗余的,这意味着您将为冗余副本使用与原始数据成比例的额外存储空间。重复的数据将消耗更多的存储空间和更多的处理时间,而没有任何好处。这就是为什么在创建冗余副本之前对数据进行重复数据删除是一个好主意:这将更快并节省您的资金。重复数据删除可以手动完成(通过使用重复删除器),也可以系统地自动使用特定文件系统,例如 zfs(启用重复数据删除)或 hashfs。

  • 纸张作为存储介质:纸张不是一种很好的存储介质,因为它的存储密度低(即您最多只能存储 100 KB 左右),并且它也可以像其他存储介质一样退化,但您无法自动检查因为它不是数字的。但是,如果您有兴趣,这里有一些软件可以做到这一点: Paper keyPaperbakOptardpaperQR BackupQR Backup (another)QR Backup (again another)QR Backup (again)最后是相关论文

  • AVPreserve 工具,最显着的是用于监视文件更改的固定性 (类似于 rfigc,但作为守护程序主动)和用于检测音频数字化工作流程中的间隙错误的插页式(非常有助于确保您将整个音频文件正确数字化为 WAV 而没有任何错误)。

常问问题

  • 我可以压缩我的数据文件和我的 ecc 文件吗?

根据经验,您应该始终以明文形式保存您的 ecc 文件,因此不要进行压缩或加密。这是因为万一ecc文件被损坏,如果压缩/加密,损坏部分的解压缩/解密可能会完全破坏ecc文件的整个结构。

您要保护的数据文件应该以明文形式保留,但如果它大大减少了文件的大小,并且如果您提高了 ecc 文件的恢复率(因此压缩可能是一种如果您有机会将文件大小减小换取更多的 ecc 文件弹性,这是一个不错的选择)。此外,请确保选择像 DEFLATE (zip) 这样的非固态压缩算法,这样即使某些部分已损坏,您仍然可以解码正确的部分(否则使用固态存档,如果一个字节损坏,整个存档可能会变得不可读) .

但是,在您压缩文件的情况下,您应该仅压缩后生成 ecc 文件,以便 ecc 文件适用于压缩存档而不是未压缩的文件,否则您可能会因为解压缩而无法更正您的文件损坏的部分可能会输出乱码,并且长度扩展损坏的部分(并且我