2009-06-08 88 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不适合你的散列值(即痛苦的冲突)时会发生什么