ฉันอ่านคำถามนี้: แคร็ก $f(x) = Cx \oplus Dx$
ถามเกี่ยวกับการค้นหาการชนกันในแฮช 64 บิตง่ายๆ และฉันคิดว่าฉันจะลองเล่นดูเพื่อความสนุก
ฉันรีบเขียนโค้ดเพื่อค้นหาการชน:
https://gist.github.com/meirmaor/b0e59352eb73cacec47d0f95c25a25fc
และยังพบการชนใกล้และไม่มีการชนเต็มจำนวนหลายครั้ง สิ่งนี้ทำให้ฉันงุนงง
คำอธิบายอัลกอริทึม:
ฉันต้องการแก้ปัญหานี้โดยใช้ RAM ขนาด 8GB ดังนั้นฉันจึงจัดสรรความยาวอาร์เรย์ Int สองชุด $2^{30}$ *(4 ไบต์ int) แต่ละรายการ
ฉันเติมข้อมูลเหล่านั้นด้วยการแฮชค่า Int ฉันใช้ 30 บิตล่างเป็นดัชนีในอาร์เรย์ทั้งสอง และเก็บ 32 บิตบนสุดในอาร์เรย์แรกและซอร์ส int ในอาร์เรย์ที่สอง
ฉันเติมโดยใช้ $2^{32}$ ค่า Int ที่เป็นไปได้ (เป็นอาร์เรย์ไบต์) และรับอัตราการเติม 98% ตามที่คาดไว้ ซึ่งแปรผันใกล้เคียงกับอุดมคติ $1-e^{-4}$ ฉันจะคาดหวัง
มันเหมือนกับตารางแฮช แต่ฉันไม่จัดการกับการชนกัน เพียงแค่เก็บค่าเดียวสำหรับแต่ละคีย์แฮช 30 บิต โดยพื้นฐานแล้วเป็นการแมประหว่างแฮช 62 บิตที่ตัดทอนกับต้นทาง 32 บิต
จากนั้นฉันลองแฮชค่าที่ยาวขึ้นด้วยคำนำหน้า Int พิเศษ และค้นหาการชนกัน อีกครั้งโดยใช้ 30 บิตที่ต่ำกว่าเป็นดัชนีไปยังอาร์เรย์ ตรวจสอบว่า 32 อันดับแรกตรงกันหรือไม่ และเราพบการชนกันที่ใกล้เคียงหรือไม่ อย่างไรก็ตาม เมื่อตรวจสอบพวกเขา ฉันไม่พบการชนกันทั้งหมด ฉันพบการชนกันเกือบมากกว่า 60 ครั้งจนถึงตอนนี้ ตรวจสอบแยกพวกเขาต่างหากว่าตรงกันใน 62 หรือ 63 บิต แต่ฉันคาดว่า 1/4 จะเป็นการชนกันทั้งหมด ฉันได้ 0
ฉันทำการทดสอบซ้ำสองครั้งก่อนเปรียบเทียบแฮช 4 ไบต์กับแฮช 8 ไบต์ที่เริ่มต้นด้วยไบต์ {small number,0,0,0} จากนั้นฉันลองเปรียบเทียบแฮชที่มีความยาวเท่ากันโดยการเติมแฮชของข้อมูลล่วงหน้าด้วยลำดับไบต์ {1,0,0,0} และเปรียบเทียบอีกครั้งด้วยคำนำหน้า {2+,0,0,0}
เป็นไปได้อย่างไร มีอะไรพิเศษในฟังก์ชันแฮชนี้ ข้อผิดพลาดแปลก ๆ ในรหัสของฉันทำให้ฉันสามารถค้นหาการชนที่ใกล้เคียงได้สำเร็จ แต่ไม่มีการชนกันทั้งหมด?
มีเหตุใกล้ชน เจอแบบนี้จะไม่ชนเต็มๆ
ตัวอย่างของการชนใกล้ที่พบ (ฉันมีจำนวนมาก):
อาร์เรย์(24, 0, 0, 0, 14, 103, 61, 80) เทียบกับ
อาร์เรย์(1, 0, 0, 0, -2, -81, 79, 79)