xorเป็นฟังก์ชั่นเริ่มต้นที่เป็นอันตรายที่จะใช้เมื่อทำการแฮช มันดีกว่าandและorแต่ก็ไม่ได้พูดอะไรมาก
xorมีความสมมาตรดังนั้นลำดับขององค์ประกอบจึงหายไป ดังนั้นพระทัยกัญชารวมเช่นเดียวกับ"bad""dab"
xor จับคู่ค่าที่เหมือนกันของคู่กับศูนย์และคุณควรหลีกเลี่ยงการจับคู่ค่า "ทั่วไป" กับศูนย์:
ดังนั้น(a,a)แมปถึง 0 และ(b,b)ได้รับการแมปเป็น 0 เนื่องจากคู่เหล่านี้มักพบบ่อยกว่าการสุ่มอาจบอกเป็นนัยว่าคุณจะพบกับการชนจำนวนมากที่ศูนย์เกินกว่าที่คุณควรจะเป็น
ด้วยปัญหาทั้งสองนี้xorกลายเป็น combiner แฮชที่ดูดีครึ่งบนพื้นผิว แต่ไม่ใช่หลังจากการตรวจสอบเพิ่มเติม
บนฮาร์ดแวร์ที่ทันสมัยการเพิ่มมักจะเร็วเท่าxor(อาจใช้พลังงานมากขึ้นเพื่อดึงสิ่งนี้ออกมายอมรับ) ตารางความจริงของการเพิ่มคล้ายกับxorในบิตของคำถาม แต่ยังส่งบิตไปยังบิตถัดไปเมื่อค่าทั้งสองเป็น 1 ซึ่งหมายความว่ามันลบข้อมูลน้อยลง
ดังนั้นhash(a) + hash(b)จะดีกว่าhash(a) xor hash(b)ถ้าa==bผลลัพธ์ออกมาเป็นhash(a)<<10
เรื่องนี้ยังคงสมมาตร ดังนั้น"bad"และ"dab"ได้รับผลลัพธ์เดียวกันยังคงมีปัญหา เราสามารถแบ่งสมมาตรนี้ด้วยราคาที่ไม่แพง:
hash(a)<<1 + hash(a) + hash(b)
hash(a)*3 + hash(b)อาคา (คำนวณhash(a)หนึ่งครั้งและแนะนำให้เก็บถ้าคุณใช้วิธีเปลี่ยนกะ) ใด ๆ คงแปลกแทนที่จะ3bijectively แผนที่จะเป็น " kบิต" จำนวนเต็มไม่ได้ลงนามกับตัวเองเป็นแผนที่ในจำนวนเต็มไม่ได้ลงนามเป็นแบบโมดูโลคณิตศาสตร์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และ1s - โดยเฉพาะอย่างยิ่งมันเป็นสิ่งที่ตรงกันข้ามกับอัตราส่วนทองคำเป็นเศษส่วนจุดคงที่ 32 บิต) ด้วยการเพิ่มและ xor แบ่งนี้สมมาตรและแนะนำบางคน "เสียง" ถ้าค่าแฮชที่เข้ามาไม่ดี (เช่นจินตนาการทุก hashes ส่วนประกอบ 0 - จับดังกล่าวข้างต้นได้ดีสร้าง smear ของ1และ0. s หลังจากแต่ละรวมของฉันไร้เดียงสา3*hash(a)+hash(b)เพียง outputs 0ใน กรณีนั้น)
(สำหรับผู้ที่ไม่คุ้นเคยกับ C / C ++ a size_tคือค่าจำนวนเต็มที่ไม่ได้ลงนามซึ่งใหญ่พอที่จะอธิบายขนาดของวัตถุใด ๆ ในหน่วยความจำบนระบบ 64 บิตโดยปกติจะเป็นจำนวนเต็ม 64 บิตที่ไม่ได้ลงชื่อบนระบบ 32 บิต เป็นจำนวนเต็ม 32 บิตที่ไม่ได้ลงชื่อ)