簡體   English   中英

在.NET中使用String.GetHashCode()的哈希質量和穩定性?

[英]Hash quality and stability of String.GetHashCode() in .NET?

我想知道.NET中String.GetHashCode()實現產生的哈希質量哈希穩定性

關於質量,我專注於算法方面(因此,哈希的質量因為它影響大型哈希表,而不是安全問題)。

然后,關於穩定性,我想知道從一個.NET版本到下一個版本可能出現的潛在版本問題。

關於這兩個方面的一些亮點將非常感激。

我無法向您提供有關質量的任何細節(盡管我認為這是非常好的,因為字符串是框架的核心類之一,可能被用作散列鍵)。

但是,關於穩定性,在不同版本的框架上生成的哈希代碼不保證是相同的,並且它在過去已經改變,所以你絕對不能依賴於版本之間的哈希代碼是穩定的( 參見此處它在1.1和2.0之間變化的引用 實際上,它甚至在同一框架版本的32位和64位版本之間也有所不同; 來自文檔

GetHashCode返回的值取決於平台。 對於特定的字符串值,它在32位和64位版本的.NET Framework上有所不同。

這是一個老問題,但我想通過提及這個關於哈希質量的微軟錯誤做出貢獻。

簡介:在64b上, 當字符串包含'\\ 0'字節時哈希質量非常低 基本上,只會對字符串的開頭進行哈希處理。

如果像我一樣,你必須使用.Net字符串來表示二進制數據作為高性能字典的關鍵,你需要注意這個bug。

太糟糕了,這是一個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中哈希碼已經不同了。

我剛剛遇到了一個相關的問題。 在我的一台計算機上(64位一台)我遇到了一個問題,我追蹤到2個不同的對象是相同的,除了(存儲的)哈希碼。 該hashcode是從一個字符串創建的....相同的字符串!

m_storedhash = astring.GetHashCode();

我不知道這兩個對象如何以不同的哈希碼結束,因為它們來自相同的字符串但是我懷疑發生了什么是在同一個.NET exe中,我依賴的類庫項目之一被設置為x86而另一個到ANYCPU,其中一個對象是在x86類lib中的方法中創建的,另一個對象(相同的輸入數據,相同的所有內容)是在ANYCPU類庫中的方法中創建的。

那么,這聽起來似乎有道理:在內存中的相同可執行文件中(不在進程之間),一些代碼可以使用x86 Framework的string.GetHashCode()和其他代碼運行x64 Framework的string.GetHashCode()?

我知道這並不包含您指定的質量和穩定性的含義,但值得注意的是,散列非常大的字符串會產生OutOfMemoryException。

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

哈希碼的質量足以滿足其預期目的,即當您將字符串用作字典中的鍵時,它們不會導致太多沖突。 我懷疑如果字符串長度相當短,它將只使用整個字符串來計算哈希碼,對於巨大的字符串,它可能只使用第一部分。

不保證版本之間的穩定性。 文檔清楚地表明散列算法可能會從一個版本更改為下一個版本,因此散列碼是短期使用的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM