【问题标题】:Hash quality and stability of String.GetHashCode() in .NET?.NET 中 String.GetHashCode() 的哈希质量和稳定性?
【发布时间】:2011-01-07 04:26:38
【问题描述】:

我想知道 .NET 中 String.GetHashCode() 实现产生的哈希质量哈希稳定性

关于质量,我专注于算法方面(因此,哈希的质量会影响大型哈希表,而不是出于安全考虑)。

然后,关于稳定性,我想知道从一个 .NET 版本到下一个版本可能出现的潜在版本控制问题。

非常感谢这两个方面的一些说明。

【问题讨论】:

    标签: c# .net string hash


    【解决方案1】:

    我无法向您提供有关质量的任何细节(尽管我认为它非常好,因为 string 是框架的核心类之一,很可能用作哈希键)。

    但是,关于稳定性,不同版本的框架产生的hash码不保证是一样的,而且过去已经发生了变化,所以绝对不能依赖版本之间hash码的稳定( see here for a reference that it changed between 1.1 and 2.0)。事实上,它甚至在相同框架版本的32位和64位版本之间存在差异; from the docs:

    GetHashCode 返回的值是平台相关的。对于特定的字符串值,它在 .NET Framework 的 32 位和 64 位版本上有所不同。

    【讨论】:

      【解决方案2】:

      这是一个老问题,但我想通过提及 this microsoft bug about hash quality 来做出贡献。

      总结:在 64b 上,当您的字符串包含 '\0' 字节时,哈希质量非常低。基本上,只有字符串的开头会被散列。

      如果像我一样,你必须使用 .Net 字符串来表示二进制数据作为高性能字典的键,你需要注意这个错误。

      太糟糕了,这是一个 WONTFIX... 作为旁注,我不明白他们怎么能说修改哈希码是一项重大更改,当代码包含时

      // We want to ensure we can change our hash function daily.
      // This is perfectly fine as long as you don't persist the
      // value from GetHashCode to disk or count on String A
      // hashing before string B. Those are bugs in your code.
      hash1 ^= ThisAssembly.DailyBuildNumber;
      

      无论如何,哈希码在 x86/64b 中已经不同了。

      【讨论】:

        【解决方案3】:

        我刚刚遇到了一个与此相关的问题。在我的一台计算机(64 位计算机)上,我遇到了一个问题,我追踪到 2 个不同的对象除了(存储的)哈希码之外是相同的。该哈希码是从一个字符串创建的......相同的字符串!

        m_storedhash = astring.GetHashCode();

        我不知道这两个对象是如何以不同的哈希码结束的,因为它们来自同一个字符串,但是我怀疑发生的事情是在同一个 .NET exe 中,我依赖的类库项目之一已设置为x86 和 ANYCPU 的另一个对象,其中一个对象是在 x86 类库中的方法中创建的,另一个对象(相同的输入数据,相同的所有内容)是在 ANYCPU 类库中的方法中创建的。

        那么,这听起来是否合理:在内存中的同一可执行文件中(而不是在进程之间),一些代码可以使用 x86 框架的 string.GetHashCode() 和其他代码 x64 框架的 string.GetHashCode() 运行?

        【讨论】:

          【解决方案4】:

          我知道这并没有真正包含您指定的质量和稳定性的含义,但值得注意的是,散列非常大的字符串会产生 OutOfMemoryException。

          https://connect.microsoft.com/VisualStudio/feedback/details/517457/stringcomparers-gethashcode-string-throws-outofmemoryexception-with-plenty-of-ram-available

          【讨论】:

            【解决方案5】:

            哈希码的质量足以满足其预期目的,即当您将字符串用作字典中的键时,它们不会导致太多冲突。我怀疑如果字符串长度相当短,它只会使用整个字符串来计算哈希码,对于大字符串,它可能只使用第一部分。

            不保证跨版本的稳定性。文档清楚地表明哈希算法可能会从一个版本更改为下一个版本,因此哈希码是短期使用的。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-03-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-07-04
              相关资源
              最近更新 更多