2012-12-20 24 views
7

C# 'da iyi bir karma algoritmaya erişim ihtiyacım olan çok sayıda vakayla karşılaştım. Bu sayede GetHashCode no'lu veriyi geçersiz karşılaştırmalar yapabiliyordum.C# FNV Hash uygulaması

FNV hash'ının gerçekten kolay/iyi/hızlı bir karma algoritma olmasını buldum. Ancak, C# uygulamasının iyi bir örneğini hiç görmedim.

şöyle FNV-1a karma algoritması çekirdeğidir: Yani

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

, ben böyle bir şey yapıyor sonunda bir sınıf için GetHashCode geçersiz zaman: İnsanları ne yapıyoruz

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; 
} 

bunu düşün

+2

Bana iyi görünüyor gibi diyebiliriz ... Eğer shoudl parantez içinde sadece yakın 'karma^x' - örneğin (hash^x) * prime' - aksi takdirde çarpma ilk önce gerçekleştirilecektir. – digEmAll

cevap

7

Sen

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

Sonra FNVConstants sınıfına bu eklemek

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

güzel. Linq'i böyle bir şey için kullanmayı hiç düşünmemiştim, ama mükemmel bir anlam ifade ediyor. Küçük, özlü. :) Teşekkürler – Keith

+4

GetHashCode asla yığında bellek ayırmamalı. –

+0

Huh? Hafızada hiç bellek ayırıyor mu? – Keith