![](/img/trans.png)
[英]Generate A Short Integer From A Unique String Without .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
的文檔提到了此方法的不同問題:
當然,它看起來很可怕,但是, GetHashCode
仍然足以用於內存中的集合,例如HashSet
或Dictionary
。
另外,請參閱這個問題: 當覆蓋 Equals 方法時,為什么覆蓋 GetHashCode 很重要?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.