【问题标题】:Confused about hashes对哈希感到困惑
【发布时间】:2010-10-19 05:38:28
【问题描述】:

假设我有一个 5000 个字符的文本块。我通过一个散列程序运行它并生成一个 40 字符长的散列。现在我运行另一个文本块,10000 个字符。它仍然会生成一个 40 个字符长的哈希值。对于任何长度的文本都是如此。

我的问题是,如果哈希都是唯一的,我不能将任何东西压缩成 40 个字符的字符串吗?

【问题讨论】:

    标签: hash


    【解决方案1】:

    散列不是唯一的。

    散列是一种尝试为输入给它的每个值生成唯一散列的技术,但不能保证它是唯一的。

    好的散列算法比差的散列算法出现重复散列值的频率要低得多。此外,散列是一个方向性的 - 这意味着你不能从散列 -> 原始,所以它不意味着压缩。

    并且:哈希不需要是唯一的。相同的输入需要通过算法转换成相同的哈希。您不使用哈希作为标识符!

    【讨论】:

      【解决方案2】:

      并非所有哈希都保证是唯一的。关于该主题的维基百科条目非常好:http://en.wikipedia.org/wiki/Hash_function

      【讨论】:

      • 补充一点,如果你知道你的整个可能的输入集,你可以为它生成完美的散列。
      【解决方案3】:

      考虑哈希的一种方式类似于人类指纹(哈希有时也称为指纹)..

      您可以将任何人“压缩”成(几乎)唯一的指纹。但是,仅凭指纹您无法知道某人是谁。这就像哈希一样,您可以轻松计算出@ 987654327@,但只给了a1b2c3,你不能随便告诉源数据。

      要反转指纹,您需要将指纹与已知people->finger-prints的数据库进行比较(如果未知指纹与Person1匹配,则未知指纹属于他们)

      使用散列,你必须做同样的事情——你有一个包含所有字符串->散列映射的数据库(称为rainbow table)。然后你用散列“a1b2c3”查找行,它显示“abcdef”是为了得到这个而散列的。另一种更常见的方法是简单地尝试每个字符组合,将它们散列并比较(brute force attack

      最后,虽然人类指纹是“唯一的”,但也有可能有两个相同的指纹,但这种可能性极小——哈希算法也是如此……一些哈希算法比其他算法更容易受到collisions 的影响。

      我的问题是,如果哈希都是唯一的,我不能将任何东西压缩成 40 个字符的字符串吗?

      理论上,散列是一种很好的压缩方法,但解压缩超出(比如说)10 个 ASCII 字符的数据是非常不切实际的。你是对的,你可以将任何内容压缩为 40 个字符的字符串,但实际上你不能解压缩它(甚至理论上也有点牵强..)

      【讨论】:

      • 不,您根本不能将其用作压缩系统。给定一个 40 个字符的散列,每个散列值将有数百万个(例如)50 个字符串。碰巧很难找到其中任何一个,但你不能指望找到“正确”的那个。
      • @bzxcv17 这种情况发生的可能性是 2^52 分之一,这是极不可能的。查找更多 SHA-1 哈希冲突。
      • @bzxcv17 如果两个文件具有相同的哈希,它们可能具有相同的内容 - 所以 git 只是将两个文件指向同一个对象。这很好,因为这意味着文件的内容只存储一次。 Pro Git book 有一个很棒的章节解释
      • @bzxcv17:我不知道 Git 会如何处理它,但这是非常不可能的。假设散列具有均匀分布,则获得特定散列的机会为 2**160 分之一,或 1,461,501,637,330,902,918,203,684,832,716,283,019,655,932,542,976 分之一。这是非常不可能的。有关碰撞概率的更多信息,请参阅this question
      • @icktoofay echo blah > file1.txt; echo blah > file2.txt 并且两者都将具有相同的哈希...我不认为@bzxcv17 是在询问哈希冲突,而是 git 如何处理具有相同内容的多个文件( Pro Git link answers nicely)。据我所知,Git 忽略了哈希冲突的可能性(没有理智的方法来处理它,而且正如你所说,这极不可能 - 所以不是问题)
      【解决方案4】:

      RSA 哈希不是唯一的。当散列两个不同的明文位时,您会产生误报的可能性非常小(大约为 1:36^40)。对于大多数应用程序来说,这种可能性被认为足够小,您可以忽略它,因为平均而言,发生意外碰撞需要数百万年的时间。

      【讨论】:

        【解决方案5】:

        散列是为了尽可能地传播,而不是为了唯一性!

        当然,达到唯一性是达到 100% 传播, 但这通常是不可能的,不管你的哈希算法有多好。

        引人注目的例子:

        例如,C# 为每个对象提供一个 Int32 代码作为 HashCode... 对于 Int64 也是如此:

               Int64 a = Int64.MaxValue;
               Int32 myHash =  a.GetHashCode();
        

        这里的结论:Int64 有 2^64 个不同的可能实例,但它们只有 2^32 个哈希码!!

        所以:Int64 的每个哈希值由(平均)共享

        4 294 967 295

        其他 Int64 的!

        这么多独特性嘿:-)

        【讨论】:

          【解决方案6】:

          考虑从Pigeonhole Principle 的角度来看这个。如果您将 n 个项目填充到较少数量的桶 k 中,则必然会有一些包含多个项目的桶。因此,要回答您的问题,没有哈希值不是唯一的。

          【讨论】:

            【解决方案7】:

            哈希不保证是唯一的,但如果您正在寻找唯一的哈希,请查看gperf。它可以为一组预先确定的输入生成一个唯一的散列函数。

            【讨论】:

              【解决方案8】:

              您可以将任何文本的签名压缩为哈希,但您无法反向计算文本是什么给您该哈希。简单地说,找出给你散列的文本是什么的唯一方法是通过散列暴力破解文本以尝试找到匹配项。

              Wikipedia

              【讨论】:

              • 再一次:仅当范围相等时。否则蛮力不会给你一个 100% 确定的解决方案,而且,根据范围,它可能远远小于 ..
              • 蛮力总是会给你正确的答案,它也可能会给你误报。定义明确的哈希的误报概率在统计上是极不可能的。
              【解决方案9】:

              不要对 .Net GetHashCode() 感到困惑。这不是很好,因为它只有 32 位,而原始问题中的 640 位(如果每个字符都是 8 位)。

              【讨论】:

              • 1.我不觉得这么糊涂,tx,原理一模一样,例子中的blob也比hash 2大很多。这根本不是问题的答案!你应该发表评论
              • 对不起,彼得,没有必要的声誉 (50) 来发表评论。但我建议您阅读 Microsoft 的 GetHashCode() 上的 cmets,因为“此方法的默认实现不得用作哈希目的的唯一对象标识符”。
              【解决方案10】:

              如果您正确使用定义明确的哈希函数,您实际上可以假设哈希结果是唯一的。

              问题,您的问题是哈希是单向函数。没有反函数可以取值并返回到原始 blob。除非您保留所有可能的原始值的巨大表(所谓的rainbow table)。

              【讨论】:

              • 只有当哈希值的范围与原始值的范围一样大时才如此,请参见 int32/64 的示例
              • 你的答案不正确。问题的问题不是单向功能!
              【解决方案11】:

              它们不是唯一的,但是在找到两个具有相同哈希值的高质量算法的不同文档之前,您更有可能死于心脏病发作,例如SHA-1

              【讨论】:

                【解决方案12】:

                【讨论】:

                  猜你喜欢
                  • 2016-10-04
                  • 2016-05-03
                  • 2015-06-29
                  • 2016-02-01
                  • 1970-01-01
                  • 2020-01-16
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-04-26
                  相关资源
                  最近更新 更多