我有 2 个 Excel 文档,我想检查它们除了文件名之外是否完全相同。
例如,文件名为fileone.xls
和filetwo.xls
。除了文件名之外,它们的内容被认为是相同的,但这正是我想要检查的。
我一直在寻找方法来查看此内容,而无需安装一堆插件。似乎没有直接的方法。
我尝试为这两个文件生成 MD5 哈希值。如果哈希值相同,是否意味着文件内容 1:1 相同?
答案1
当哈希值相同时,是否意味着文件内容 1:1 相同?
所有文件都是字节的集合(值 0-255)。如果两个文件的 MD5 哈希值匹配,则这两个字节集合极有可能完全相同(相同顺序、相同值)。
两个文件生成相同 MD5(128 位哈希值)的可能性很小。概率为:
两个哈希值意外碰撞的概率是 1/2 128,即 340 十亿分之一、282 十亿分之一、366 十亿分之一、920 八亿分之一、938 七亿分之一、463 六亿分之一、463 五亿分之一、374 千万亿分之一、607 万亿分之一、4317.68 亿 211 千 456 分之一。(来自堆栈溢出。
哈希只能在“一个方向”上工作 - 即,您获取一组字节并获得一个哈希,但不能获取哈希并返回一组字节。
密码学依赖于此(这是在不知道两件事物是什么的情况下比较这两件事物的一种方法。)
大约在 2005 年,人们发现了获取 MD5 哈希值并创建与该哈希值匹配的数据的方法,即创建两个具有相同 MD5 哈希值的文档(碰撞攻击)。 请参阅下面@user2357112 的评论。这意味着攻击者可以创建两个具有相同 MD5 的可执行文件,如果您依靠 MD5 来确定信任哪一个,那么您就会被欺骗。
因此,MD5 不应用于加密或安全。例如,在下载网站上发布 MD5 以确保下载完整性是不好的。您应该避免依赖您自己未生成的 MD5 哈希来验证文件或数据内容。
如果您自己生成,您知道您不会对自己怀有恶意(希望如此)。因此,对于您自己使用来说,这是可以的,但如果您希望其他人能够复制它,并且您希望公开发布 MD5 哈希,则应使用更好的哈希。
请注意,两个 Excel 文件可能在相同的行和列中包含相同的值,但由于格式、样式、设置等不同,文件的字节流可能完全不同。
如果您想要比较文件中的数据,请先将其导出为具有相同行和列的 CSV,以删除所有格式,然后对 CSV 进行哈希处理或比较。
答案2
实际上,是的,相同的加密哈希值意味着文件是相同的,只要文件不是由攻击者或其他恶意实体制作的。随机的与任何精心设计的加密哈希函数的碰撞都非常小,在实践中以及在没有主动攻击者的情况下可以忽略不计。
但一般来说,不,我们不能说两个任意文件具有相同的哈希值确实表示它们是相同的。
加密哈希函数的工作方式是接受任意长度的输入,并输出根据输入计算出的固定长度值。某些哈希函数有多种输出长度可供选择,但输出在某种程度上仍然是固定长度的值。该值最多为几十个字节;目前常用的具有最长输出值的哈希算法具有 512 位输出,而 512 位输出为 64 个字节。
如果哈希函数的输入比哈希函数的输出长,则必须删除一些保真度以使输入适合输出。因此,必须存在多个长度大于输出长度的输入,从而生成相同的输出。
让我们以当前的主力算法 SHA-256 为例。它输出 256 位(或 32 字节)的哈希值。如果您有两个文件,每个文件的长度恰好为 32 字节,但不同,则无论文件的内容如何,它们(假设算法没有缺陷)的哈希值都应该不同;从数学角度来说,哈希是一个将 2 256输入空间映射到 2 256输出空间的函数,这应该可以做到不发生冲突。但是,如果您有两个文件,每个文件的长度为 33 字节,则必须存在一些输入组合为两个文件提供相同的 32 字节输出哈希值,因为我们现在将 2 264输入空间映射到 2 256输出空间;在这里,我们可以很容易地看到,平均而言,每个输出应该存在 2 8 个输入。进一步说,对于 64 字节文件,每个输出应该存在 2 256个输入!
加密哈希函数的设计使得它计算困难组合一个输入以产生特定输出,或组合两个输入以产生相同输出。这称为原像攻击反抗或者碰撞攻击反抗。 它不是不可能的找到这些碰撞;它的目的只是真的,真的,真的,真的很难。(碰撞攻击的一个特殊情况是生日攻击。
有些算法比其他算法更能抵御攻击者。MD5 目前普遍被认为已经完全失效,但据我观察,它仍然表现良好第一个原像抵抗力。SHA-1 同样可以被有效破解;原像攻击已被证实,但需要特定条件,尽管没有理由相信这种情况会一直存在;俗话说,攻击总是越来越好,永远不会变得更糟。目前,SHA-256/384/512 仍然被认为在大多数情况下是安全的。然而,如果你只是想看看两个非恶意制作,有效文件相同,那么其中任何一个都应该足够了,因为输入空间已经足够受限,你最感兴趣的是随机碰撞。如果你有任何理由相信这些文件是恶意制作的,那么你至少需要使用目前认为安全的加密哈希函数,这将下限设为 SHA-256。
第一的原像是找到一个产生特定输出哈希值的输入;第二原像是找到一个输入,它能给出与另一个指定输入相同的输出;碰撞是找到两个产生相同输出的输入,而不考虑输出是什么,有时也不考虑输入是什么。
尽管如此,重要的是要记住这些文件的数据表示可能大不相同,但显示效果却完全相同。因此它们看起来相同即使它们的加密哈希值不匹配,但如果哈希值匹配,那么它们就是极有可能看起来一样。
答案3
这是一个概率游戏...哈希能够表示有限数量的值。
如果我们考虑一个假设的(非常弱的)8 位哈希算法,那么这可以表示 256 个不同的值。当您开始通过算法运行文件时,您将开始得到哈希值……但不久之后,您将开始看到“哈希冲突“这意味着两个不同的文件被输入到算法中,并且它产生了相同的哈希值作为其输出。显然,这里的哈希值不够强,我们不能断言“哈希值匹配的文件具有相同的内容“。
扩展哈希的大小并使用更强大的加密哈希算法可以显著减少冲突,并提高我们对具有相同哈希的两个文件具有相同内容的信心。
尽管如此,我们永远无法达到 100% 的确定性——我们永远不能声称一定具有相同哈希值的两个文件确实具有相同的内容。
在大多数/许多情况下这都是可以的,比较哈希值是“够好了“,但这取决于您的威胁模型。
最后,如果您需要提高确定性级别,那么我建议您执行以下操作:
如果您需要 100% 确定,那么一定要从哈希开始,但如果哈希匹配,则再对两个文件进行逐字节的比较。
此外,正如其他人指出的那样......Word 和 Excel 等应用程序生成的文档的复杂性意味着文本、数字、可见布局可以相同,但文件中存储的数据可以不同。
Excel 在这方面尤其糟糕 - 只需打开电子表格保存它(已经完成没有什么) 可以生成一个新文件,其内容不同。
答案4
简短回答:A加密哈希应该可以帮助您合理地确信具有匹配哈希值的文件是相同的。除非故意制作,否则两个略有不同的文件具有相似哈希值的可能性非常小。但是当比较和验证可能被故意篡改的文件时,MD5 不是一个好选择。(使用其他哈希函数,如 SHA3 或 BLAKE2。)
长答案:理想的哈希函数是为每一块独特的数据创建一个几乎独特的加密哈希。换句话说,我们肯定知道这个世界上有两个文件的哈希值相冲突,这两个文件自然结合在一起的可能性非常小。
十年前,我决定必须尽可能远离 MD5。(当然,直到昨天,我才想起这样做的错误原因;十年是很长的时间,你看。我重新回顾了过去的备忘录以记住原因并编辑了这个答案。)你看,1996 年,人们发现 MD5 容易受到碰撞攻击。9 年后,研究人员能够创建具有相同哈希值的 PostScript 文档和(哎哟!)X.509 证书对!MD5 显然被破解了。(Megaupload.com 也在使用 MD5,当时哈希冲突方面存在很多问题,这给我带来了麻烦。)
因此,我得出结论,虽然 MD5 曾经(现在仍然)可靠地用于比较良性文件,但必须完全停止使用它。我推断,对它的依赖有变成放纵和虚假信心的风险:一旦你开始使用 MD5 哈希值比较文件,有一天你会忘记安全细则,并比较两个故意制作成具有相同哈希值的文件。此外,CPU 和加密处理器不太可能添加对它的支持。
然而,原始海报使用 MD5 的理由更少,因为:
- 只要比较两个文件,逐字节比较实际上比生成自己的 MD5 哈希值要快。如果比较三个或更多文件……那么,现在您有正当理由了。
- OP 指定了“查看此内容的方法,而无需安装一堆插件”。Windows PowerShell 的获取文件哈希命令可以生成 SHA1、SHA256、SHA384、SHA512 和 MD5 哈希值。在具有硬件支持 SHA 哈希函数的现代计算机上,生成它们的速度更快。