簡體   English   中英

如果不能保證字符串或整數的 getHashCode() 是唯一的,為什么要使用它?

[英]If getHashCode() for string or integer is not guaranteed to be unique why use it?

正如我在標題中寫的那樣。

如果在您的應用程序中使用 getHashCode() 不安全,為什么要使用它? (對於字符串和整數)我想用它來交叉方法,除了 Linq 模型中的方法或創建我自己的 IEqualityCompare 類。 感覺就像一個機會 - 如果它不是 100% 安全?

或者我錯過了什么?

正如在https://docs.microsoft.com/中的 String.GetHashCode 方法中引用的那樣

重要的

如果兩個字符串對象相等,則 GetHashCode 方法返回相同的值。 但是,每個唯一的字符串值都沒有唯一的哈希碼值。 不同的字符串可以返回相同的哈希碼。

不保證哈希碼本身是穩定的。 對於單個 .NET 版本,相同字符串的哈希碼可能因 .NET 實現、.NET 版本和 .NET 平台(例如 32 位和 64 位)而異。 在某些情況下,它們甚至可能因應用領域而異。 這意味着同一程序的兩次后續運行可能會返回不同的哈希碼。

因此,永遠不應該在創建它們的應用程序域之外使用哈希碼,永遠不應該將它們用作集合中的關鍵字段,也不應該持久化它們。

最后,如果您需要加密強哈希,請不要使用哈希代碼代替加密哈希函數返回的值。 對於加密哈希,請使用從 System.Security.Cryptography.HashAlgorithm 或 System.Security.Cryptography.KeyedHashAlgorithm 類派生的類。

有關哈希碼的更多信息,請參閱 Object.GetHashCode。

我認為讓您感到困惑的是,您認為哈希碼映射到值的地址,但事實並非如此。

把它想象成書架,哈希碼映射到書架的地址。 如果其中兩本HashCode相同,則放在同一個Shelf中,並且有3本書的書架地址,dictionary只檢查書架上的三本書,而不是所有的書。 所以唯一的哈希碼越多,字典查找的速度就越快。

當您創建IEqualityComparer如果您可以使GetHashCode()返回唯一值,則使用它的 Dictionary 或 HashSet 的執行速度將比有許多重復項時更快。

檢查這個例子:

public int GetShashCode(string ojb)
{
     return obj.Length;
}

雖然它比遍歷整個字符串快得多,但它不是很獨特(雖然它是有效的)

這個例子也是有效的,但更糟糕的選擇:

public int GetShashCode(string ojb)
{
     return (int)obj[0];
}

根據您可以猜測的字符串的內容,您可以制作更好的哈希碼(例如,您知道它是這種格式的社會安全號碼:“XXX-XX-XXXX”,其中每個 X 代表一個數字)將是一個不錯的選擇:

public int GetShashCode(string ojb)
{
     return int.Parse(obj.Replace("-",""));
}

如果在您的應用程序中使用 getHashCode() 不安全,為什么要使用它?

GetHashCode有不同的目的。 如果您需要對字符串進行相等測試,您可能應該使用String.Equals==運算符,它們可以保證正常工作。

哈希碼並不是為每個可能的字符串生成唯一數字的方法,這是不可能的。 下面是哈希函數的定義:

散列函數是可用於將任意大小的數據映射到固定大小值的任何函數。

它只是將一組幾乎無限的字符串映射到一組(相對)非常有限的整數。 如果您需要將大量字符串均勻分布到較小的“存儲桶”中,您可能需要使用哈希碼。 散列碼廣泛用於基於散列的集合,例如HashSet

GetHashCode的文檔提到了此方法的不同問題:

  • 該方法可以在 .Net 的不同域/機器/版本上為相同的字符串生成不同的結果。 這意味着將散列外部存儲為某種唯一標識符以供以后使用並不是一個好主意;
  • 結果在密碼學上不強,所以如果你需要一個牢不可破的密碼鹽,你不應該使用它。

當然,它看起來很可怕,但是, GetHashCode仍然足以用於內存中的集合,例如HashSetDictionary

另外,請參閱這個問題: 當覆蓋 Equals 方法時,為什么覆蓋 GetHashCode 很重要?

暫無
暫無

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

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