當使用GetHashCode()
方法獲得字符串的哈希碼時,是否有機會返回零或所用的算法是否保證不成立?字符串的GetHashCode()方法是否可以返回零?
我問的原因是我有一個用例,我需要發明一個空字符串的散列,我正在考慮使用零而不是散列一些常量字符串。如果我這樣做,我有多大可能發生碰撞(除非存在碰撞總是可能的明顯事實)
當使用GetHashCode()
方法獲得字符串的哈希碼時,是否有機會返回零或所用的算法是否保證不成立?字符串的GetHashCode()方法是否可以返回零?
我問的原因是我有一個用例,我需要發明一個空字符串的散列,我正在考慮使用零而不是散列一些常量字符串。如果我這樣做,我有多大可能發生碰撞(除非存在碰撞總是可能的明顯事實)
沒有辦法明確回答這個問題。 String.GetHashCode()的行爲被記錄爲未定義,並且在框架版本之間可能會有變化,並且在32位和64位系統之間會有所不同。
如果您選擇了其他值,您可能會發生碰撞。零將是一個非常合理的默認值。
如果Nullable.GetHashCode()存儲空值,則返回0,因此返回零的散列碼有一些先例。
存在散列爲零的字符串。出於所有實際目的,原始問題肯定可以回答「是」。如果答案是「總是可以找到一個散列爲零的字符串」,那麼回答可以是除了不合格的「是」之外的任何其他答案的唯一方式。順便說一句,如果我設計的框架,我會指定一個好的'GetHashCode()'實現永遠不應該返回零「緩慢」;如果一個需要大量時間執行的哈希函數產生零,那麼'GetHashCode'應該返回其他值。 – supercat
如果存在這樣的規則,那麼考慮根據需要緩存哈希代碼的類可以安全地使用零來指示「哈希未緩存」,因爲即使一些對象始終有GetHashCode調用它們,它也不會有很大的作用。如果沒有這樣的規則,那麼需要在具有計算速度較慢的哈希代碼的對象之間執行大量比較的程序可能會在大部分時間快速運行,直到一個哈希值爲零的對象被創建,從而可能會降低性能一個數量級或更多。 – supercat
GetHashCode()
只需要哈希碼是一致的。它不需要是唯一的。所以零是一個有效的,但非常天真的哈希值:)
顯然,這將導致哈希表中的許多衝突。
至於字符串哈希碼,我猜在某些條件下是可能的。
這是有風險的,可以將空字符串強制爲空字符串。例如:
string nullstr = null;
string notnull = nullstr + nullstr;
也許有點古怪,但你會有一個helluvatime當它發生時調試問題。簡單的解決方案是使用string.Empty.GetHashCode(),並不要求哈希代碼是唯一的。
如果答案是「Yes,'string.GetHashCode()'有時可以返回0」,那麼會在代碼中真正改變嗎? – svick
不,考慮到碰撞總是可以發生,任何數字都會發生,在這種情況下,選擇零而不是某個其他任意常量似乎更合理 – RobV