2009-06-08 230 views
3

我正在C#中爲System.Drawing.Point類實現自定義GetHashCode。我的方法目前無法以下要求:最快的哈希碼生成器.NET

var hashA = MyGetHashCode(new Point(1, 0)); 
var hashB = MyGetHashCode(new Point(0, 1)); 
var hashC = MyGetHashCode(new Point(0, 0)); 
var hashD = MyGetHashCode(new Point(1, 1)); 
Assert.AreNotEqual(hashA^hashB, hashC^hashD); 

要通過這個測試,我敢肯定,使用新SHA256Managed()ComputeHash(currentHash)會做。但是還有其他更快的哈希算法?我知道SHA256是關於安全性的,我不需要它。

+1

你是怎麼想出你的散列函數應該通過該測試的? – mquander 2009-06-08 13:08:44

+0

@ mquander當然似乎很奇怪,但其他一些Equals函數依賴於一個簡單的GetHashCode實現,它依次依賴於我自定義的Point.GetHashCode方法 – 2009-06-08 13:16:25

+0

@mquander這完全是關於不在Equals和GetHashCode中重複代碼,並使它們等價。 – 2009-06-08 13:19:51

回答

6

一個簡單的散列?怎麼是這樣的:

(17 * point.X) + (23 * point.Y); 

或爲較爲明顯的熵:

int hash = -1047578147; 
hash = (hash * -1521134295) + point.X; 
hash = (hash * -1521134295) + point.Y; 

(從C#的匿名類型代號)

+1

馬克,這將肯定履行斷言,但沒有界限(大X或Y會溢出)...如果你允許溢出,那麼它沒有一個良好的分配 – 2009-06-08 13:10:00

+1

它會包裝(未檢查);分配是,AFAIK ,很好...這是C#編譯器使用的方法; -p – 2009-06-08 13:12:42

+0

你從哪裏得到常數?順便說一句Jorge是對的。 – 2009-06-08 13:27:30

1

我知道這是不會回答你的問題,但爲了其他讀者的緣故,我必須提到您正在改變框架的內置方法的默認行爲。按照文檔:
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

的 的GetHashCode方法的默認實現不執行不 保證唯一的返回值 不同對象。此外,.NET Framework不保證 GetHashCode方法的默認實現 ,並且其值 返回的值將在 不同版本的.NET Framework之間相同。因此,此方法的默認 實施必須 不作爲唯一對象 標識符用於散列目的。

3
  • 你爲什麼要這麼做?當然System.Drawing.Point已經有一個很好的散列函數了?

  • 您知道測試並不代表嚴格的要求,對吧?哈希代碼不一定是唯一的。

  • 如果你真的想要一個真正好的散列的問題座標,你可能想從this page開始散列多個整數。

1

一個簡單的精靈哈希實現(這是在Delphi中,shoudl是容易翻譯)

function ElfHash(id : string; tableSize : integer) : integer; 
var 
    i : integer; 
    h,x : longint; 
begin 
    h := 0; 
    // Obtener el valor numérico 
    for i := 1 to Length(id) do 
    begin 
    h := (h shl 4) + Ord(id[i]); 

    x := h and $F0000000; 
    if x <;>; 0 then 
     h = h xor (x shr 24) xor x; 
    end; 
    // Ajustar al tamaño de la tabla 
    result := h mod tableSize; 
end; 
0

如果您事先知道您的積分值介於0和N之間,則可以使用hashcode = X+Y*N;這是一個相當明顯的可能的散列值。它不是隨機的,具有醜陋的重複,並且通常非常愚蠢。假設N是2的冪,這相當於連接兩個點的位。它具有完美的均勻分佈和無碰撞。

我以前用這個策略取得了很好的效果,但承認它有一些真實的(但明顯的)限制。最大的一個是當N足夠大以至於N^2不適合你的散列值(即痛苦的衝突)時會發生什麼