xorkarma yaparken kullanmak için tehlikeli bir varsayılan işlevdir. Bundan daha iyidir andve orbu fazla bir şey ifade etmez.
xorsimetriktir, bu yüzden elemanların sırası kaybolur. Böylece "bad"karma ile aynı birleştirir "dab".
xor çift olarak aynı değerleri sıfıra eşler ve "ortak" değerleri sıfıra eşlemekten kaçınmalısınız:
Böylece (a,a)0 ile eşlenir ve 0 ile (b,b)eşlenir. Bu çiftler neredeyse her zaman rastlantısallığın ima edebileceğinden daha yaygın olduğu için, sıfırdan çok çarpışmanız gerekir.
Bu iki problemle, xoryüzeyde yarı iyi görünen bir karma birleştirici olur, ancak daha fazla incelemeden sonra olmaz.
Modern donanımda, genellikle yaklaşık olarak hızlı ekleme xor(muhtemelen bunu çıkarmak için daha fazla güç kullanır). Eklemenin doğruluk tablosu şuna benzerxor söz konusu bite , ancak her iki değer 1 olduğunda da bir sonraki bite biraz gönderir. Bu, daha az bilgi sildiği anlamına gelir.
Yani hash(a) + hash(b)daha iyidir hash(a) xor hash(b)eğer ki a==b, sonucudurhash(a)<<1 0 yerine.
Bu simetrik kalır; böylece "bad"ve "dab"aynı sonucu elde etmek sorun olmaya devam ediyor. Bu simetriyi mütevazı bir maliyetle kırabiliriz:
hash(a)<<1 + hash(a) + hash(b)
aka hash(a)*3 + hash(b). ( hash(a)vardiya çözümünü bir kez hesaplamanız ve saklamanız tavsiye edilir). Bunun yerine herhangi bir tek sabit 3, bijektif kolarak kendi kendine bir " -bit" işaretsiz tamsayıyı eşler, çünkü işaretsiz tam sayılardaki harita 2^kbazıları için matematik modülondur kve herhangi bir tek sabit göreceli olarak asaldır 2^k.
Daha meraklı bir versiyon için, boost::hash_combineetkili bir şekilde inceleyebiliriz :
size_t hash_combine( size_t lhs, size_t rhs ) {
lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
return lhs;
}
Burada , bazı ek ve bir xor seedile bir sabit (temelde rasgele 0s ve 1s - özellikle 32 bit sabit nokta fraksiyonu olarak altın oranın tersidir) ile bazı kaydırılmış versiyonlarını ekliyoruz . Bu sonları simetri ve gelen karma değerleri yani 0'a her bileşen karmaları hayal (fakir iseler bazı "gürültü" tanıtır - Yukarıdaki kolları de, bir karalama üreten 1ve 0her peşinde birleştirmek Benim saf. 3*hash(a)+hash(b)Basitçe çıkışları a0 in O vaka).
(C / C ++ ile aşina olmayanlar için, a size_tbellekteki herhangi bir nesnenin boyutunu tanımlamak için yeterince büyük olan işaretsiz bir tamsayı değeridir. 64 bit sistemde genellikle 64 bit işaretsiz bir tamsayıdır. 32 bit sistemde , 32 bit işaretsiz bir tam sayı.)