【问题标题】:Hash Code and Checksum - what's the difference?哈希码和校验和 - 有什么区别?
【发布时间】:2010-10-02 09:55:45
【问题描述】:

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

即两个数据块产生相同数字哈希/校验和值的概率足够低,以至于在应用程序中可以忽略。

那么我们是否有两个词来表示同一事物,或者哈希码和校验和之间是否存在重要区别?

【问题讨论】:

  • 总结以下答案:哈希码将输入减少到一个小数字,以最大限度地减少冲突的机会。另一方面,校验和将输入减少到一个小数字,从而最大限度地减少冲突的机会。您可以通过任意改写该描述来使一种声音与另一种声音不同。
  • @DanStahlke - 不,这不是下面的答案所说的。是的,它们都将输入减少到较小的数量。但是有很多很多方法可以做到,如何选择使用什么算法呢?这取决于你的目标。总结前两个答案:校验和的目标是“检测最常见的错误”。对于您的场景中“最常见”的任何错误,选择产生不同校验和的算法。如果您担心一个或两个位被切换,您可以选择一种算法来保证检测到该特定错误!这是一个非常具体的权衡。
  • @DanStahlke - 另一方面,哈希码涵盖了广泛的可能权衡。如果我们指的是用于制作哈希表的值,我们知道会有发生冲突,而且很多。这是一个非常不同的权衡(比校验和)。我们正在尝试平均减少冲突。我们不保证任何事情。可能有一些输入仅相差一位,但产生相同的散列。这很好,如果平均我们得到散列值的良好分布。然而对于校验和来说是不可接受的。

标签: language-agnostic hash computer-science checksum


【解决方案1】:

我会说checksum 必然hashcode。但是,并非所有哈希码都能产生良好的校验和。

校验和有一个特殊用途——它验证或检查数据的完整性(有些可以通过允许error-correction 来超越)。 “好”校验和易于计算,并且可以检测多种类型的数据损坏(例如,1、2、3 个错误位)。

哈希码只是描述了将数据映射到某个值的mathematical function。当用作数据结构(例如哈希表)中的索引方式时,需要较低的冲突概率。

【讨论】:

  • 也许可以将一个用作另一个,但考虑到它们有不同的设计目标,这只会混淆问题。
  • @gumbo:不,不是每个哈希码都是校验和。请参阅下面 MSalters 中的字符串示例。
【解决方案2】:

Wikipedia 说得好:

校验和函数与哈希有关 功能、指纹、随机化 函数和加密哈希 职能。然而,这些中的每一个 概念有不同的应用 因此不同的设计目标。 校验位和奇偶校验位是 校验和的特殊情况, 适用于小数据块 (例如社会安全号码、银行 帐号,计算机单词, 单个字节等)。一些 纠错码是基于 特殊校验和,不仅检测 常见的错误,但也允许 要恢复的原始数据 某些情况。

【讨论】:

  • 看完之后,我还在想有什么区别。
  • @kirk.burleson - 我会说它们是相同的原理,但在实践中总是需要权衡。在不同的情况下,应用不同的权衡,因此使用不同的方法。并不是真的有两个不同的词的理由,只是说如果你搜索校验和的好技术,你可能会发现一组与搜索哈希码不同的算法。
【解决方案3】:

现在它们是可以互换的,但是在过去,校验和是一种非常简单的技术,您可以将所有数据(通常以字节为单位)相加,并在末尾添加一个带有该值的字节。然后您希望知道是否有任何原始数据已损坏。类似于校验位,但带有字节。

【讨论】:

    【解决方案4】:

    当提到为文件或数据创建的代码(数字或其他)时,我倾向于使用单词校验和,这些代码可用于检查文件或数据没有损坏.我遇到的最常见的用法是检查通过网络发送的文件是否未被更改(有意或无意)。

    【讨论】:

    • 因为校验和并不难以逆转,这表明它们不适合检查是否有人故意更改。
    【解决方案5】:

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

    • 哈希码 - 设计为在其域中随机(以尽量减少哈希表等中的冲突)。加密哈希码也被设计成在计算上无法逆转。
    • 校验和 - 旨在检测数据中最常见的错误,并且通常可以快速计算(用于对快速数据流进行有效校验和)。

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

    【讨论】:

    • 另外值得一提的是,哈希码的非加密版本可以在计算时间(接近 CRC)和错误检测之间提供良好的折衷,无论是故意的还是只是通信错误/比特腐烂(CRC不能指望检测到故意篡改,因为故意设计碰撞相对容易)。
    • 对我来说,您回答中的关键短语是校验和旨在检测最常见的错误。对,就是那样。它是一种哈希算法,已被选择为可能数据损坏产生不同的值。这是一个特定的目的,并导致特定的算法,该算法对此进行优化 - 取决于人们关注的扰动类型。
    • 功能校验和可能在其整个域中发生大量冲突,只要您检查的错误不太可能导致此类冲突。例如,校验和中可能有一些你不关心的周期性,因为错误永远不会把你带到那里。 (一个很好的例子是奇偶校验,它只防止单比特错误。)所以一个好的校验和的定义本质上取决于错误模型。
    【解决方案6】:

    确实有一些不同:

    • 校验和只需要在输入不同时(尽可能频繁)不同,但它们的计算速度几乎同样重要。
    • 哈希码(用于哈希表)具有相同的要求,此外它们应均匀分布在代码空间中,尤其是对于相似的输入。
    • 加密散列具有更加更严格的要求,即给定散列,您不能构造产生此散列的输入。计算时间排在第二位,根据应用程序的不同,甚至可能希望哈希的计算速度非常慢(以对抗暴力攻击)。

    【讨论】:

    • 我认为不同输入的校验和不同没有任何好处。它们只是用于检查完整性,而不是用于散列。
    • @Mehrdad:那么您如何建议检查完整性而不针对不同的输入得到不同的结果?
    • 呃,也许我说错了?我指的是你说“尽可能”的部分——我只是说没有理由让它们像哈希一样不可预测或“远”。只要输入发生典型变化时校验和有一些变化,它就是一个很好的校验和。与散列形成对比,散列的目标也是将事物尽可能均匀/随机/不可预测/“远”分布到它们的共同域上。
    • 我想你只是误解了我所说的“尽可能”的意思——我只是说碰撞应该尽可能少,尽管它们当然是不可避免的。我会改变措辞。
    • @ToolmakerSteve:已经 5 年多了,但是是的,我想这就是我所指的。校验和并不是为了防止对手。即使您可以找到一个 1 KB 的字符串与 1 MB 的字符串产生相同的校验和,这对于校验和来说并不是真正的问题,因为意外发生的概率几乎为零。
    【解决方案7】:

    哈希码和校验和都用于从数据项创建短数值。不同之处在于校验和值应该改变,即使只是对数据项进行了很小的修改。对于散列值,要求仅仅是现实世界的数据项应该具有不同的散列值。

    一个明显的例子是字符串。字符串的校验和应该包括每一位,并且顺序很重要。另一方面,哈希码通常可以实现为有限长度前缀的校验和。这意味着“aaaaaaaaaaaba”的哈希值与“aaaaaaaaaaab”相同,但哈希算法可以处理这种冲突。

    【讨论】:

    • 这个答案为我敲响了警钟。所以数据完整性不是散列的重点。
    【解决方案8】:

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

    • 校验和用于确定是否输入中的某些内容发生了变化。

    • 哈希码用于找出如果输入中的某些内容发生了变化,以便在各个哈希码值之间具有尽可能大的“距离”。

      此外,与此规则相反,可能对哈希函数有进一步的要求,例如能够尽早形成哈希码值的树/集群/桶。

      如果您添加一些共享的初始随机化,您就会了解现代加密/密钥交换的概念。


    关于概率:

    例如,假设输入数据实际上总是在变化(100% 的时间)。并假设您有一个“完美”的哈希/校验和函数,它生成一个 1 位的哈希/校验和值。因此,对于随机输入数据,您将在 50% 的时间内获得不同的哈希/校验和值。

    • 如果您的随机输入数据中恰好有 1 位发生了变化,那么无论输入数据有多大,您都可以 100% 检测到这一点。

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

      ...

    这意味着,如果输入数据中的位数是哈希/校验和值中位数的数倍,那么对于不同的输入值,您实际获得不同哈希/校验和值的概率会降低,并且不是常数

    【讨论】:

      【解决方案9】:

      校验和可防止意外更改。

      加密哈希可以防止非常积极的攻击者。

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

      但是,如果您假设有人主动且智能地修改了网络上的消息,并且您想防范此类攻击者,那么请使用加密哈希(我忽略了对哈希进行加密签名,或使用辅助通道或这样,因为这个问题似乎并没有回避这一点)。

      【讨论】:

      • “加密哈希”增加了“哈希”和“校验和”之间的混淆。 “加密校验和”更好,因为它没有。
      【解决方案10】:

      虽然散列和校验和的相似之处在于它们都基于文件的内容创建一个值,但散列不同于 创建校验和。校验和旨在验证(检查) 数据完整性和识别数据传输错误,而哈希 旨在创建数据的唯一数字指纹。

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

      【讨论】:

        【解决方案11】:

        校验和只是通过 oring(通过逻辑加法因此求和)从数据字段生成的数字。校验和具有检测生成它的数据字段内的任何位或位数的损坏的能力,即它检查所有错误,它不能纠正它们。校验和是哈希,因为校验和的大小小于原始数据。是的,您会遇到冲突,因为校验和对数据字段中的位位置根本不敏感。

        循环冗余校验 (CRC) 是完全不同的,更复杂的 并且不称为校验和。它是多项式级数的应用,具有纠正任何选定数量的个体的能力生成它的数据字段中的损坏位。 CRC 的创建会产生比原始数据字段更大的数字(与校验和不同) - 因此名称中包含“冗余”一词以及您为纠错功能付出的代价。因此,CRC 不是散列,不能混淆或命名为校验和,因为冗余必然会增加原始数据的大小。

        【讨论】:

          【解决方案12】:

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

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

          6 在不同的输入中出现两次。散列的目的只是将输入值映射到输出值,唯一性不是交易的一部分。因此,在哈希世界中,产生相同输出的两个不同输入是可以的。

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

          【讨论】:

            【解决方案13】:
            • hash code(Sip Hash) 通常用于基于哈希表的结构(Dictionary、Set、HashMap...),其中基本操作具有恒定的时间 - O(1)
            • check sum(MD5, SHA) 用于表示数据完整性

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

            [Java hash code]

            【讨论】:

              猜你喜欢
              • 2011-03-22
              • 2023-03-04
              • 2011-08-31
              • 2016-03-20
              • 2012-04-03
              • 2012-09-12
              • 2011-05-29
              • 2016-11-23
              • 2021-04-06
              相关资源
              最近更新 更多