2012-12-20 41 views
7

我有很多情況下需要在C#中使用體面的哈希算法,從重寫GetHashCode到對數據執行快速比較/查找。FNV Hash的C#實現

我發現FNV哈希是一個非常簡單/很好/快速的哈希算法。但是,我從來沒有見過一個C#實現的好例子。

的FNV-1A散列算法的核心是如下:

hash = OFFSET_BASIS 
foreach (object value in object) 
{ 
    hash = hash^value.GetHashCode() 
    hash = hash * FNV_PRIME 
} 

所以,當我重寫GetHashCode一類我最終做這樣的事情:

public static class FNVConstants 
{ 
    public static readonly int OffsetBasis = unchecked((int)2166136261); 
    public static readonly int Prime = 16777619; 
} 

public override int GetHashCode() 
{ 
    int hash = Constants.FNVConstants.OffsetBasis; 
    hash = (hash^EntityId.GetHashCode()) * Constants.FNVConstants.Prime; 
    hash = (hash^FromDate.GetHashCode()) * Constants.FNVConstants.Prime; 
    hash = (hash^ToDate.GetHashCode()) * Constants.FNVConstants.Prime; 
    return hash; 
} 

什麼人想想這個?

+2

它看起來好像沒什麼問題...你shoudl正好接近'哈希^ x'括號 - 例如'(hash^x)* prime' - 否則首先執行乘法運算。 – digEmAll

回答

7

你可以添加到您的FNVConstants

public static int CreateHash(params object[] objs) 
{ 
    return objs.Aggregate(OffsetBasis, (r, o) => (r^o.GetHashCode()) * Prime); 
} 

然後調用它像

public override int GetHashCode() 
{ 
    return FNVConstants.CreateHash(EntityId, FromDate, ToDate); 
} 
+0

不錯。我從來沒有想過使用Linq這樣的東西,但它非常有意義。小巧,簡潔。 :)謝謝 – Keith

+4

GetHashCode不應該在堆上分配內存。 –

+0

咦?它在哪裏分配堆內存? – Keith