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

我的理解是,哈希代码和校验和是类似的东西-一个数值,为一个数据块计算,这是 相对而言唯一的。

也就是说。两个数据块产生相同的哈希/校验和值的概率非常低,以至于可以为了应用程序的目的而忽略它。

那么,我们是用两个词来表示同一件事情,还是哈希代码和校验和之间有重要的区别呢?

65075 次浏览

我会说 校对 是必然的 a 散列码。然而,并不是所有的哈希码都能做好校验和。

校验和有一个特殊的用途——它验证或 支票数据的完整性(有些可以通过允许 更正错误来超越这一点)。“好的”校验和很容易计算,可以检测许多类型的数据损坏(例如一、二、三个错误位)。

散列码简单地描述了将数据映射到某个值的 数学函数。当在数据结构(例如散列表)中作为索引的一种方法使用时,需要较低的冲突概率。

现在,它们是可以互换的,但是在过去,校验和是一种非常简单的技术,你可以把所有的数据加起来(通常是以字节为单位) ,然后在最后添加一个字节,这个值放在。.那你就有希望知道原始数据是否被破坏了。类似于检查位,但使用字节。

我倾向于使用校验和这个词来指代为一个文件或一段数据创建的代码(数字或其他) ,这些代码可以用于 检查完毕,该文件或数据没有被损坏。我遇到的最常见的用法是检查通过网络发送的文件没有被更改(故意或其他方式)。

他们每个人背后都有不同的目的:

  • 哈希代码-设计成在其域内是随机的(以尽量减少哈希表中的冲突等)。密码哈希码也被设计成计算上不可逆的。
  • 校验和——设计用来检测数据中最常见的错误,并且通常可以快速计算(用于有效的校验和快速数据流)。

在实践中,同样的函数通常对两个目的都有好处。特别是,如果您能够承担计算成本,那么加密的强哈希代码是一个很好的校验和(随机错误几乎不可能破坏强哈希函数)。

的确存在一些差异:

  • 校验和只需要在输入不同时(尽可能经常地)有所不同,但它们的快速计算几乎同样重要。
  • 哈希代码(用于哈希表)具有相同的要求,而且它们应该均匀地分布在代码空间中,特别是对于类似的输入。
  • 加密哈希对 很多有更严格的要求,即给定一个哈希,就不能构造产生该哈希的输入。计算时间排在第二位,根据应用程序的不同,哈希值的计算速度可能需要非常慢(以对抗暴力攻击)。

哈希码和校验和都用于从数据项创建简短的数值。不同之处在于校验和值应该更改,即使只对数据项做了很小的修改。对于哈希值,需求仅仅是实际数据项应该具有不同的哈希值。

字符串就是一个明显的例子。字符串的校验和应该包括每一位和顺序问题。另一方面,散列码通常可以实现为有限长度前缀的校验和。这意味着“ aaaaaaaaaaba”将与“ aaaaaaaaaaab”一样散列,但是散列算法可以处理这样的冲突。

哈希码和校验和函数之间的区别在于,它们的设计目的不同。

  • 校验和用于发现 如果输入中的某些内容发生了变化。

  • 一个散列码是用来找出 如果的输入已经改变了 还有,有尽可能多的“距离”之间的个人散列码值。

    此外,与此规则相反,也许吧对散列函数还有进一步的要求,比如能够在早期形成树/集群/散列代码值桶。

    如果加入一些共享的初始随机化,就会得到现代加密/密钥交换的概念。


关于概率:

例如,让我们假设输入数据实际上总是在变化(100% 的时间)。假设您有一个“完美”的 hash/checksum 函数,它生成一个1位的 hash/checksum 值。因此,对于随机输入数据,50% 的情况下会得到不同的 hash/checksum 值。

  • 如果您的随机输入数据中只有1位发生了变化,那么无论输入数据有多大,您都可以在100% 的时间内检测到该变化。

  • 如果随机输入数据中的2位发生了变化,那么检测到“变化”的概率除以2,因为这两种变化可能会相互抵消,而且没有任何哈希/校验和函数会检测到输入数据中的2位实际上是不同的。

    ...

这意味着,如果输入数据中的比特数是散列/校验和值中比特数的数倍,那么对于不同的输入值,实际获得不同散列/校验和值的概率就会降低,不是一个常数也会降低。

校验和可以防止意外更改。

加密散列可以防止非常有动机的攻击者。

当您在线上发送位时,可能会意外地发生一些位被翻转、删除或插入。为了让接收方能够检测(有时是纠正)这样的事故,发送方使用校验和。

但是,如果你假设有人主动和智能地修改电线上的消息,你想要防止这种类型的攻击者,那么使用加密散列(我忽略了加密签名散列,或使用辅助通道等,因为这个问题似乎没有逃避这一点)。

虽然哈希和校验和类似,因为它们都根据文件的内容创建值,但哈希不同于 创建校验和。校验和的目的是验证(检查) 数据的完整性和识别数据传输错误,而散列 是为了创建一个独特的数字指纹的数据。

资料来源: CompTIA 安全 + 网络安全基础指南-第五版-Mark Ciampa-第191页

校验和仅仅是一个数字,它是通过 oring (通过逻辑加法从而求和)从数据字段生成的。校验和有能力检测数据字段中的任何比特或比特数的损坏,即它检查错误,但不能纠正错误。校验和是一个散列,因为校验和的大小比原始数据小。是的,您将会有冲突,因为校验和对数据字段中的位位置根本不敏感。

一个循环冗余校验(CRC)是完全不同的东西,更复杂的 abc0它是一个多项式序列的应用,它有能力纠正任何选定的数量的个别损坏的比特在数据领域内产生。CRC 的创建会导致比原始数据字段大的数字(与校验和不同)-因此名称包括单词“冗余”和错误纠正能力的代价。因此 CRC 不是散列,不能混淆或命名为校验和,因为冗余必然会增加原始数据的大小。

在 Redis 集群数据分片中,它使用 hash slot来决定去哪个节点。以下面的模除为例:

123 % 9 = 6
122 % 9 = 5
141 % 9 = 6

6在不同的输入端出现两次。散列的目的仅仅是将输入值映射到输出值,而唯一性不在其中。因此,两个不同的输入,产生相同的输出是好的,在哈希的世界。

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

  • hash code(Sip Hash)通常用于基于哈希表的结构(Dictionary、 Set、 HashMap...) ,其中基本操作的时间为常量 O (1)
  • check sum(MD5,SHA)用于表示数据完整性

主要的区别是,check sum必须是 独一无二,而 hash code对于不同的对象可以是相同的。例如在 Java 或 Swift 中,hash code受到 Int的限制。通常与 equals函数结合使用。两个不同的对象可以有相同的 hash code

[ Java 哈希码]