重新压缩 .gz 和 .bz2 文件以获得相同的哈希/校验和(修改时间戳?)

重新压缩 .gz 和 .bz2 文件以获得相同的哈希/校验和(修改时间戳?)

我希望每月复制 wikimedia 转储的全部内容,并将它们上传到亚马逊冰川和/或磁带备份和/或可以在公司倒闭/电磁脉冲(如果有一天存在)后幸存下来的第三个备份介质。

问题在于磁盘空间,时间不是什么大问题。

我发现当我解压每月数据库的内容时简单维基并使用 7-zip 重新压缩,最终得到 3% 的压缩率。

我怀疑重新压缩一年的转储将导致作为固定存档的压缩率显著提高,因为它应该只存储更改(或者会吗?)但为了数据完整性,如果没有冗余数据,这可能是一个坏主意,而 7-zip 似乎不支持。我正在考虑为此目的保留两个额外的副本,并且仍然使用 7-zip。

解压文件进行备份的问题意味着我丢失了存储在原始转储站点上的哈希/校验和。

我想减压一份文件然后重现相同的哈希/校验和通过使用与压缩时相同版本的 gzip/bzip2 以及相同的选项/方法再次压缩它。

这可能吗?我需要“伪造”修改时间戳吗?我如何确定使用了哪些选项?

答案1

您有点不明白“相同”一词的含义,也不明白您到底比较和散列了什么。假设您有两个不同的压缩存档文件,拆包后它们都返回与身份进行比较的文件。让我们将此解压后的内容视为“相同的数据”。这很有可能,您已经知道了。

“相同”的直接后果是解压数据是该数据的哈希值也将与身份进行比较,即将是“相同的数据”。

这是否意味着档案馆本身“相同的数据”?

不。

压缩档案可以看作是表示数据量越大,存储所需的计算机内存就越少,这就是我们使用压缩数据流的原因。压缩数据流可以看作一组指令,这些指令将由特殊的解压器处理。解压器处理这些指令,并希望重建原始数据。

例如,这是 LZ77 算法的一个想法:生成一个直接包含原始字符的流,也可能包含一些魔术指令,这些指令被理解为“回溯 N 个字节并从那里开始复制 M 个字节”。事实上,你可以生成几组不同的此类指令,它们仍然输出相同的数据;例如,字符串“abababab”可以这样存储,即“ab{-2,2}{-4,2}{-6,2}”、“ab{-2,2}{-2,2}{-2,2}”或“ab{-2,6}”(最后一个想法非常聪明)。这些“压缩”表示是否相同?不,它们的长度不同,并且包含不同的数字作为“魔术指令”的参数;总的来说,它们是不同的指令集最终返回相同的原始数据。(请注意,如果要将此类压缩流存储到文件中,您将使用一些有效的二进制打包,而不是花括号和 ASCII 数字。为了让您感兴趣,我只描述了一半的优秀旧 ZIP 算法。)

另一个例子是编程语言。比较:

#include <stdio.h>
int main(void) {
    printf("Hello World!\n");
    return 0;
}
Begin
WriteLn("Hello World!")
End.

这些程序会产生相同的输出吗?当然。它们一样吗?不,它们是用不同的语言编写的!


档案中有“相同的数据”,但档案本身是指令集,那些指令不同的,尽管按照它们操作,你最终会得到“相同的数据”。当你对档案进行校验时,你也会对这些指令进行校验他们自己,而不是遵循它们的结果。因此您将获得不同的哈希值。

压缩器是一种先进的程序,它试图找到一组最佳指令,这些指令仍将返回给定的数据。它经过高度优化,可运行于所有计算机。因此,输出取决于环境:它返回的特定指令集(压缩文件)可能取决于许多因素,包括压缩器程序的版本、压缩期间可用的内存、可用处理器核心的数量及其类型等。一些压缩算法甚至依赖于真正的随机性!有无数这样的环境,因此很难找到与生成给定存档文件的环境类似的“那个”环境来再次生成它。

你正在解决一个错误的任务。如果你想对某个东西进行校验/哈希处理,那么它必须是可以重新创建的东西确切地. 压缩流是不是您可以准确重现什么。

相关内容