xor
हैशिंग के लिए उपयोग करने के लिए एक खतरनाक डिफ़ॉल्ट फ़ंक्शन है। यह बेहतर है and
और or
, लेकिन यह बहुत कुछ नहीं कहता है।
xor
सममित है, इसलिए तत्वों का क्रम खो गया है। तो "bad"
हैश के रूप में ही गठबंधन होगा "dab"
।
xor
नक्शे शून्य के समरूप मानों को जोड़ते हैं, और आपको "सामान्य" मानों को शून्य करने से बचना चाहिए:
तो (a,a)
0 पर मैप हो जाता है, और (b,b)
0. के लिए मैप भी हो जाता है। क्योंकि ऐसी जोड़ियां लगभग हमेशा से ज्यादा सामान्य होती हैं, जैसे कि यादृच्छिकता का अर्थ हो सकता है, आप शून्य से कई टकरावों की तुलना में दूर होना चाहिए।
इन दो समस्याओं के साथ, xor
एक हैश कॉम्बीनेटर होता है जो सतह पर आधा सभ्य दिखता है, लेकिन आगे के निरीक्षण के बाद नहीं।
आधुनिक हार्डवेयर पर, आमतौर पर उपवास के रूप में जोड़ते हैं xor
(यह संभवतः इस बंद को खींचने के लिए अधिक शक्ति का उपयोग करता है, संयुक्त रूप से)। सच्चाई की तालिका को जोड़ना xor
सवाल में बिट पर समान है , लेकिन जब दोनों मान 1 होते हैं तो यह अगले बिट को भी भेजता है। इसका मतलब है कि यह कम जानकारी मिटाता है।
तो उस hash(a) + hash(b)
से बेहतर hash(a) xor hash(b)
है अगर a==b
, परिणाम hash(a)<<1
0 के बजाय है।
यह सममित रहता है; इसलिए "bad"
और "dab"
एक ही परिणाम प्राप्त करना एक समस्या है। हम मामूली लागत के लिए इस समरूपता को तोड़ सकते हैं:
hash(a)<<1 + hash(a) + hash(b)
उर्फ hash(a)*3 + hash(b)
। ( hash(a)
यदि आप शिफ्ट समाधान का उपयोग करते हैं तो एक बार गणना करना और भंडारण की सलाह दी जाती है)। किसी भी विषम स्थिरांक के बजाय अपने आप में 3
एक " k
-bit" अहस्ताक्षरित पूर्णांक को मैप करेगा, क्योंकि अहस्ताक्षरित पूर्णांकों पर मानचित्र 2^k
कुछ के लिए गणित मोडुलो है k
, और किसी भी विषम स्थिरांक के लिए अपेक्षाकृत प्रमुख है 2^k
।
एक भी कट्टर संस्करण के लिए, हम जांच कर सकते हैं boost::hash_combine
, जो प्रभावी रूप से है:
size_t hash_combine( size_t lhs, size_t rhs ) {
lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
return lhs;
}
यहाँ हम seed
एक स्थिरांक के साथ कुछ बदलाव किए गए संस्करणों को जोड़ते हैं (जो मूल रूप से यादृच्छिक 0
s और 1
s है - विशेष रूप से यह कुछ अनुपात और एक xor के साथ सुनहरे अनुपात का एक 32 बिट निश्चित अंश के रूप में व्युत्क्रम है)। यह समरूपता को तोड़ता है, और कुछ "शोर" का परिचय देता है यदि आने वाले हैशेड मान खराब होते हैं (यानी, प्रत्येक घटक हैश की 0 से कल्पना करें - ऊपर यह अच्छी तरह से संभालता है, प्रत्येक संयोजन के बाद 1
और 0
एस का एक धब्बा पैदा करता है । मेरा भोलापन 3*hash(a)+hash(b)
बस एक 0
में आउटपुट करता है । उस मामले में)।
(उन लोगों के लिए जो C / C ++ से परिचित नहीं हैं, एक size_t
अहस्ताक्षरित पूर्णांक मान है जो स्मृति में किसी भी वस्तु के आकार का वर्णन करने के लिए पर्याप्त है। 64 बिट सिस्टम पर, यह आमतौर पर 64 बिट अहस्ताक्षरित पूर्णांक है। 32 बिट सिस्टम पर। , एक 32 बिट अहस्ताक्षरित पूर्णांक।)