哈希码和校验和 - 有什么区别?

141

我的理解是,哈希码和校验和是类似的东西 - 它们都是计算数据块的数字值,这个数字值是相对唯一的。

也就是说,两个数据块生成相同的数字哈希/校验和的概率非常低,可以在应用程序中忽略。

那么,哈希码和校验和是同一个东西吗?还是它们之间有重要的区别?


4
总结以下回答:散列码将输入缩小为一个较小的数字,以最小化冲突的可能性。而校验和则以一种最小化冲突的方式将输入缩小到一个小数字。您可以通过任意重新表述该描述来使它们听起来不同。 - Dan Stahlke
4
@DanStahlke - 不,下面的答案并不是这样说的。 是的,它们都将输入缩小到较小的数字。 但是有很多种方法可以做到这一点,如何选择要使用的算法呢?这取决于你的目标。 总结前两个答案:校验和的目标是“检测最常见的错误”。选择能够产生不同校验和的算法,以检测在你的场景中“最常见”的任何错误。如果你担心会切换一两个位,你可以选择一个保证检测该特定错误的算法!这是非常具体的一种权衡。 - ToolmakerSteve
1
@DanStahlke - 另一方面,哈希码涵盖了可能的广泛权衡。如果我们指的是用于制作哈希表的值,我们知道会有碰撞,很多碰撞。这是一个非常不同的权衡(而不是校验和)。我们试图平均减少碰撞。我们不保证任何事情。可能有一些输入仅相差一个位,但产生相同的哈希值。如果平均我们得到良好的哈希值分布,则完全可以接受。但对于校验和来说是不可接受的。 - ToolmakerSteve
更多关于哈希值的用途和重点。 - CGTheLegend
@DanStahlke的评论并不是为了总结问题的现有答案。如果您认为这样的总结会有用,您可以将总结作为一个独立的答案发布。请参阅帮助中心:"不建议使用评论进行以下任何操作:[...]回答问题或提供现有答案的替代解决方案;而是发布一个实际的答案(或编辑以扩展现有答案);" - undefined
13个回答

0
在 Redis 集群数据分片中,它使用“哈希槽”来决定数据应该存储在哪个节点上。例如下面的取模运算:
123 % 9 = 6
122 % 9 = 5
141 % 9 = 6

6 在不同的输入中出现了两次。哈希的目的仅是将输入值映射到输出值,独特性并不是其中的一部分。因此,在哈希的世界中,产生相同输出的两个不同输入是可以接受的。

另一方面,校验和必须区分输出,即使输入中的一个位发生变化,因为它的目的不是映射,而是检测数据损坏。因此,在校验和中,产生相同输出的两个不同输入是不可接受的。


-1

哈希码 vs 校验和

  • 哈希码(Sip Hash)通常用于基于哈希表的数据结构(字典、集合、哈希映射等)[Swift dictionary, Set],其中基本操作具有恒定时间 - O(1)
  • 校验和(MD5、SHA)用于指示数据完整性。例如,为创建数字签名计算校验和[About]

主要区别在于校验和必须是唯一的,而哈希码可以对应不同的对象相同。例如,在Java或Swift中,您的哈希码受到Int的限制。通常与equals函数一起使用。两个不同的对象可以具有相同的哈希码

[Java hash code]


-5

校验和是从数据字段中通过逻辑或运算(因此求和)生成的数字。校验和具有检测数据字段中任何位或多个位的损坏的能力,即它仅检查错误,无法纠正错误。校验和是哈希值,因为校验和的大小比原始数据小。是的,您会遇到冲突,因为校验和对数据字段中的位位置完全不敏感。

循环冗余校验(CRC)是完全不同的东西,更加复杂,并且不被称为校验和。它是多项式序列的应用,具有纠正数据字段中任意数量的单个损坏位的能力。创建CRC会产生一个比原始数据字段大的数字(不像校验和),因此包括“冗余”一词的名称以及您为纠错能力所付出的代价。因此,CRC不是哈希值,不能将其与校验和混淆或命名,因为冗余必然增加了原始数据的大小。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接