两个文件的相同加密哈希或校验和是否意味着它们相同?

sam*_*sam 60 checksum

我有 2 个 excel 文档,除了文件名之外,我想检查它们是否完全相同。

例如,文件被称为fileone.xlsfiletwo.xls。除了文件名,它们的内容被假定是相同的,但这是我想要检查的。

我一直在寻找无需安装一堆插件的方法来查看此内容。似乎没有直接的方法。

我已经尝试为两个文件生成 MD5 哈希值。当哈希值相同时,这是否意味着文件内容是 1:1 相同的?

Law*_*ceC 93

当哈希值相同时,这是否意味着文件内容是 1:1 相同的?

所有文件都是字节的集合(值 0-255)。如果两个文件的 MD5 哈希匹配,则这两个字节集合极有可能完全相同(相同的顺序,相同的值)。

两个文件生成相同 MD5(128 位哈希)的可能性很小。概率为:

只有两个散列意外碰撞的概率为1/2 128为1在340 undecillion 282 decillion 366 nonillion 920千的十六次方938 septillion 463 sextillion 463三次方374万亿6070000亿431十亿7.68亿211000 456(从上一个答案的StackOverflow。)

散列旨在“仅在一个方向”工作 - 即您获取一组字节并获得一个散列,但您不能获取一个散列并取回一组字节。

密码学依赖于此(这是在不知道这些东西是什么的情况下可以比较两个东西的一种方式。)

大约在 2005 年,发现了采用 MD5 散列并创建与该散列匹配的数据的方法,从而创建具有相同 MD5 散列的两个文档(碰撞攻击)。 请参阅下面的@user2357112 的评论。这意味着攻击者可以创建两个可执行文件,例如,具有相同的 MD5,如果您依赖 MD5 来确定信任哪个,您将被愚弄。

因此 MD5 不应用于加密或安全。例如,在下载站点上发布 MD5 以确保下载完整性是不好的。根据您自己没有生成的 MD5 哈希来验证文件或数据内容是您想要避免的。

如果你自己生成,你就知道你对自己没有恶意(希望如此)。所以对于你的使用,是可以的,但是如果你希望其他人能够复制它,并且你想要公开发布 MD5 散列,则应该使用更好的散列。


请注意,两个 Excel 文件可能在相同的行和列中包含相同的值,但由于格式、样式、设置等不同,文件的字节流完全不同。

如果要比较文件中的数据,请先将其导出为具有相同行和列的 CSV,以去除所有格式,然后对 CSV 进行散列或比较。

  • Excel 文件和其他办公文档也可能具有不同的哈希值,因为它们已被打开并重新保存而没有更改任何内容,这是由于文件中的元数据在上次保存的日期时间中存储了一个新值。 (107认同)
  • 奖励:如果您已导出到 CSV,您可以使用古老的 `diff` 或类似实用程序来实际确认文件是逐字节相同的,而不仅仅是具有相同的哈希。 (29认同)
  • 获取散列并创建与散列匹配的数据是一种原像攻击。我相信 MD5 目前容易受到碰撞攻击,但我认为原像或第二原像攻击目前不可行。 (18认同)
  • @Tim 你在说什么?他说:将它们导出为 CSV 并使用 `diff -s` 来检查 CSV 是否相同。事实上,您甚至可以对 excel 文件进行“diff -s”:如果“diff”表示它们相同,则无需进行 CSV 比较。 (2认同)
  • @Bakuriu 显然,我的评论措辞很差 - 我的意思是导出到 CSV 会丢失很多信息 - 特别是公式、图表、条件和标准格式。 (2认同)
  • 你如何写关于 MD5 的不安全性而不建议像 SHA256 这样更好的散列...... (2认同)

use*_*ser 37

实际上,是的,相同的加密散列意味着文件是相同的,只要文件不是由攻击者或其他恶意实体制作的。与任何设计良好的加密散列函数发生随机冲突的几率非常小,在实践中和没有主动攻击者的情况下可以忽略不计。

然而,一般来说,不,我们不能说具有相同散列的两个任意文件肯定意味着它们是相同的。

加密散列函数的工作方式是采用任意长度的输入,并输出根据输入计算出的固定长度值。一些散列函数有多种输出长度可供选择,但输出在某种程度上仍然是一个固定长度的值。该值最多可达几十个字节;现在常用的输出值最长的hash算法都是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。

第一个原像是找到产生特定输出哈希值的输入;第二个原像是找到一个输入,该输入与另一个指定输入的输出相同;碰撞是找到产生相同输出的两个输入,而不考虑它是什么,有时甚至不考虑输入是什么。

综上所述,重要的是要记住,这些文件可能具有非常不同的数据表示形式,但仍然显示完全相同。因此,他们可能看起来是一样,即使他们的密码散列不匹配,但是如果哈希匹配,那么他们极有可能出现相同的。

  • @Gilles:恰恰相反。迈克尔的措辞完全正确,“保证”具有误导性(或者,实际上是错误的)。具有相同哈希值的两个文件不匹配(尽管被恶意修改)的可能性极低,在实践中可以忽略。然而,它_不是零_。通常有可能,无论出于何种原因,不同的输入_将_产生相同的哈希值,甚至可能远高于 2^-128(加密算法是黑魔法,算法可能以一种微妙的、未知的方式存在缺陷,并且我们无法 100% 确定)。 (9认同)
  • @Gilles "_effectively zero_" 仍然 **_not zero_**,这意味着仍然有一些(不可否​​认的小)概率,两组不同的数据将导致相同的哈希。你不能反驳。 (5认同)
  • @Attie:两个不相关的文件散列到相同值的概率远远低于许多其他可能出错的事情(例如随机位错误破坏磁盘上的文件)的概率,因此不值得防范巧合匹配。防范故意设计的比赛可能是值得的,但意外的比赛不太可能发生,因此任何防范它们的努力都可能花在其他地方更好。 (5认同)
  • @吉尔斯错了。你不能一口气告诉我,有一种可能性,无论**你**评价它有多小,可能会发生意外碰撞,然后在下一个受赠者中不会发生碰撞。这么说是非常具有误导性的,因为它暗示了散列算法的一个属性,该属性已知是完全错误的。 (3认同)
  • 如果哈希匹配,那么文件要么是故意冲突的结果,要么不是,然后它们_保证_相同。意外碰撞的概率纯粹是理论上的。说“如果哈希匹配,那么它们很可能看起来相同”是一种误导:如果存在恶意并且是碰撞情况,那么它们不太可能相同,否则概率实际上为零,它是不是一些需要防御的低概率事件。 (2认同)

Att*_*tie 10

这是一个概率游戏......哈希能够表示有限数量的值。

如果我们考虑一个假设的(非常弱的)8 位哈希算法,那么这可以表示 256 个不同的值。当您开始通过算法运行文件时,您将开始得到散列……但不久您将开始看到“散列冲突”。这意味着两个不同的文件被输入到算法中,并且它产生与其输出相同的哈希值。很明显,这里的哈希值不够强,我们不能断言“具有匹配哈希值的文件具有相同的内容”。

扩展散列的大小并使用更强大的加密散列算法可以显着帮助减少冲突,并提高我们对具有相同散列的两个文件具有相同内容的信心。

也就是说,我们永远无法达到 100% 的确定性——我们永远无法确定具有相同哈希值的两个文件确实具有相同的内容。

在大多数/许多情况下,这很好,比较哈希值“足够好”,但这取决于您的威胁模型。

最终,如果您需要提高确定性水平,那么我建议您执行以下操作:

  1. 使用强大的散列算法(如果您需要防范潜在的恶意用户,则不再认为MD5就足够了)
  2. 使用多种哈希算法
  3. 比较文件的大小 - 额外的数据点可以帮助识别潜在的冲突,但请注意,演示的MD5 冲突不需要更改数据的长度。

如果您需要 100% 确定,那么一定要从哈希开始,但如果哈希匹配,则对两个文件进行逐字节比较。


此外,正如其他人所指出的...... Word 和 Excel 等应用程序生成的文档的复杂性意味着文本、数字、可见布局可以相同,但文件中存储的数据可以不同。

Excel 在这方面尤其糟糕 - 只需打开一个电子表格保存它(什么都不做)就可以生成一个具有不同内容的新文件。

  • * MD5 不再被认为是足够的* 在密码学上是非常正确的,但对于唯一性检查(在没有恶意的情况下,例如,如果您控制输入)它又好又快(128 位应该足够了) (6认同)
  • 不,这不是概率游戏。您错误地估计了意外碰撞的可能性。它只是不会发生。在比较过程中稍微翻转的可能性更大。另一方面,在某些情况下,可能会发生故意碰撞,这根本不是概率游戏。 (5认同)
  • “_跟进两个文件的逐字节比较。_”如果您要进行文件比较,您最好先进行……阅读每个文件的所有内容进行计算是没有意义的他们的哈希只是为了重新读取两个文件来比较它们! (4认同)
  • @TripeHound这取决于文件是否都是本地文件...拨打适合您情况的电话。 (3认同)
  • @mbrig:32 位散列将有很大的意外不匹配风险。但是,使用 128 位或 256 位会产生*巨大* 差异。使用 128 位,十亿只猴子每人输入十亿个大小合适的真正随机文档将有大约 0.3% 的机会创建两个具有相同哈希的文档。使用 256 位,即使数十亿只猴子可以在 10 亿年内每秒输入 10 亿个大小合适的随机文档,但这些非数以亿计的文档中的任何一个具有巧合匹配哈希值的可能性也将微乎其微。 (3认同)
  • @Gilles 不,正如 Attie 所说,它实际上是一个概率游戏,基于哈希中有多少位以及您希望使用多少个文​​件。对于普通桌面用户(CRC32 仍然流行用于某些类型的下载视频文件),32 位哈希可能会很好(除非恶意),但不适用于谷歌规模的大数据文件系统。 (2认同)

小智 6

简短的回答:一个加密散列是应该帮助你有理由相信,随着配套文件的哈希值是相同的。除非故意制作,否则两个略有不同的文件具有相似哈希值的可能性很小。但是在比较和验证可能被故意篡改的文件时,MD5 是一个糟糕的选择。(使用另一个哈希函数,如 SHA3 或 BLAKE2。)

长答案:理想的散列函数是为每个唯一的数据创建几乎唯一的加密散列的函数。换句话说,我们肯定知道在这个宇宙中有两个文件的哈希值发生冲突,这两个文件自然地走到一起的机会小得离谱。

十年前,我决定我必须尽可能远离 MD5。(当然,直到昨天,我才记错了这样做的原因;十年是很长的时间,你看。我重温了我过去的备忘录以记住原因并编辑了这个答案。)你看,在 1996 年,MD5 被发现容易受到碰撞攻击。9 年后,研究人员能够创建成对的 PostScript 文档和(哎哟!)具有相同哈希值的 X.509 证书!MD5 明显坏了。(Megaupload.com 也在使用 MD5,当时有很多关于哈希冲突的麻烦事给我带来了麻烦。)

因此,我得出的结论是,虽然 MD5 是(并且仍然)在比较良性文件方面是可靠的,但必须完全停止使用它。我认为对它的依赖有变成放纵和错误自信的风险:一旦你开始使用它们的 MD5 散列比较文件,有一天你会忘记安全细则,并比较故意制作具有相同散列的两个文件。此外,CPU 和密码处理器不太可能增加对它的支持。

然而,原始海报使用 MD5 的理由更少,因为:

  1. 只要只比较两个文件,逐字节比较实际上比生成自己的 MD5 哈希要快。比较三个或更多文件......好吧,现在你有一个正当的理由。
  2. OP 指定了“无需安装一堆插件即可查看此内容的方法”。Windows PowerShell 的Get-FileHash命令可以生成 SHA1、SHA256、SHA384、SHA512 和 MD5 哈希值。在硬件支持 SHA 哈希函数的现代计算机上,生成它们的速度更快。

  • 您可以创建您自己选择的任何长度的加密哈希函数,true;但它有一个*固定*的长度,无论如何都适用鸽笼原则。一般的答案是:“仅通过比较它们的哈希值,您无法确定这两个文件是否相同”。 (6认同)
  • @KamilMaciorowski 从理论上讲,是的,我可以。我定制的哈希函数可以简单地生成最大文件的副本。但我没有兴趣进一步讨论这个问题。事实是,你投反对票的理由相当于吹毛求疵,只是为了证明你更聪明,结果适得其反。现在你不能收回投票。 (2认同)

Gil*_*il' 6

如果两个文件具有相同的 MD5 哈希值,并且它们都不是特制的,那么它们是相同的。制作具有相同 MD5 哈希值的文件有多难取决于文件格式,我不知道使用 Excel 文件有多容易。

因此,如果您有自己的文件并希望找到重复的文件,那么 MD5 是安全的。如果您编写了其中一个文件,而另一个文件来源可疑,则 MD5 仍然是安全的(获得具有相同 MD5 校验和的不同文件的唯一方法是制作两个文件)。如果您不信任的人向您发送预算提案,然后又发送了另一个他们声称相同的文件,那么 MD5 可能不够。

为避免任何风险,请使用 SHA-256 或 SHA-512 而不是 MD5。如果两个文件具有相同的 SHA-256 哈希值,则它们是相同的。SHA-512 也是如此。(理论上它们可能会有所不同,但这种意外发生的可能性远小于您的计算机在验证过程中稍微翻转的可能性,而只是无关紧要。至于有人故意制作两个文件相同的哈希值,没有人知道如何对 SHA-256 或 SHA-512 执行此操作。)

如果两个 Excel 文件具有不同的哈希值,则它们是不同的,但无法知道它们的差异有多大。它们可能具有相同的数据但格式不同,或者它们的属性可能不同,或者它们可能由不同的版本保存。事实上,如果 Excel 与 Word 类似,那么只需保存文件即可更新其元数据。如果只想比较数字和文本数据而忽略格式和属性,可以将电子表格导出为 CSV 进行比较。

如果您有可用的 Unix/Linux 工具,那么您可以cmp用来比较两个文件。要比较同一台机器上的两个文件,校验和只会让事情变得更加复杂。


sty*_*fly 5

诸如 MD5 或 SHA 之类的哈希具有固定长度,可以说它是 300 个字母数字字符(实际上它们更短并且不使用整个字母数字字符集)。

假设文件由字母数字字符组成,大小最大为 2GB。

您可以很容易地看到,比可能的哈希值有更多的文件(大小高达 2GB)。鸽巢原则说一些(不同的)文件必须具有相同的哈希值。

此外,如 shattered.io 1 所示,您可以拥有两个不同的文件:shattered.io/static/shattered-1.pdf 和 shattered.io/static/shattered-2.pdf,它们具有相同的 SHA-1 哈希值,同时被完全不同。

1 SHA1 是比 md5“更强”的散列算法


And*_*nle 5

我有 2 个 excel 文档,除了文件名之外,我想检查它们是否完全相同。

从实用的角度来看,直接比较文件以找出它们是否不同比为每个文件计算散列然后比较该散列要快。

要计算散列,您必须读取两个文件的全部内容。

要通过直接比较确定它们是否相同,您只需要读取两个文件的内容,直到它们不匹配。一旦发现差异,您就会知道这些文件并不相同,并且您不必再从任一文件中读取任何数据。

在您这样做之前,您可以简单地比较两个文件的大小。如果尺寸不同,则内容不能相同。