Score:4

ชนใกล้แต่ไม่ชนเต็มจำนวน

ธง in

ฉันอ่านคำถามนี้: แคร็ก $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)

Meir Maor avatar
in flag
ความพยายามครั้งต่อไปของฉันคืออัลกอริทึมสองนิ้ว O(1) หน่วยความจำ แต่ฉันยังไม่รู้ว่าทำไมความพยายามครั้งแรกจึงล้มเหลว
Score:5
ธง ng

การเพิ่มที่สำคัญในภายหลัง: ตอนนี้ฉันรู้แล้วว่าโค้ดพยายามค้นหาการชนกันของ 64 บิต $\operatorname{hash}$ ยอมรับข้อความ 64 บิต ถ้าอย่างนั้น $\operatorname{hash}$ เป็นการคัดค้านมันจะไม่ชนกัน มีความต่อเนื่องระหว่าง bijection และฟังก์ชั่นสุ่มและไม่มีการประกัน $\operatorname{hash}$ พฤติกรรมส่วนใหญ่เหมือนในภายหลัง ตรงกันข้าม มันเป็นหน้าที่ภายใน $f(x)=C\,x\oplus D\,x\bmod2^{64}$ ไม่มีการแพร่กระจายที่ถูกต้อง นั่นคือ, $x\equiv x'\pmod{2^i}\หมายถึง f(x)\equiv f(x')\pmod{2^i}$, ดังนั้น $f$ เป็นฟังก์ชันรอบแฮชที่ไม่ดี สิ่งนี้อาจอธิบายความยากในการค้นหาการชนด้วยวิธีการที่ออกแบบมาสำหรับฟังก์ชันสุ่ม ในภายหลังฉันถือว่าหนึ่งใน:

  • พื้นที่ข้อความสำหรับ $x$ เป็น $ข$-บิตด้วย $ข$ มีขนาดใหญ่กว่า (เอาต์พุต 64 บิต)
  • เราพยายามหาการชนกัน $x,x'$ ดังนั้น $\operatorname{hash}(p\mathbin\|x)=\operatorname{hash}(p'\mathbin\|x')$ ที่ไหน $p$ และ $p'$ ได้รับการแก้ไขคำนำหน้าที่แตกต่างกัน $x,x'$ เป็น $b=64$-นิดหน่อย, $x\ne x'$.

ฉันสงสัยว่าประเด็นสำคัญอีกอย่างคือใน

ฉันเติมข้อมูล (อาร์เรย์) โดยแฮชค่า Int

มันถูกแฮช เพิ่มขึ้น ค่า Int ค่อนข้างเป็นไปได้ที่จะสร้างฟังก์ชันในลักษณะที่ค่าที่เพิ่มขึ้นในช่วงเวลาใหญ่ๆ ไม่ชนกัน และเป็นไปได้ทีเดียวที่ฟังก์ชัน $\operatorname{hash}$ การค้นหาการชนกันจะทำงานเช่นนั้น ดังนั้นความพยายามใด ๆ ที่จะค้นหาการชนกันระหว่างค่าที่ต่อเนื่องกันจึงล้มเหลว

พิจารณาตัวอย่างฟังก์ชันที่ไม่มีการชนกันของอินพุตในช่วงเวลาสั้นๆ $H(x)=\left(263x+\left(\operatorname{MD5}(x)\bmod256\right)\right)\bmod2^{64}$. มันถือ $H(x)-H(x')\equiv263(x-x')+(r-r')\pmod{2^{64}}$, กับ $r,r'\in[0,255]$ เนื่องจากได้รับเป็นไบต์สุดท้ายของ MD5; ดังนั้น $\lvert r-r'\rvert<256$. ดังนั้นหาก $x\ne x'$วิธีเดียวที่จะได้รับ $H(x)=H(x')$ คือว่า $\lvert x-x'\rvert$ มีขนาดใหญ่เป็นอย่างน้อย $\lfloor 2^{64}/263\rfloor$ซึ่งจะไม่เกิดขึ้นติดต่อกัน $x$ ในช่วงเวลาเล็กน้อย

เมื่อพยายามค้นหาการชนกันของฟังก์ชันแฮชแบบสุ่มที่ไม่เพียงพอ $H$การแก้ไขง่ายๆ คือการค้นหาการชนกันของฟังก์ชันที่สุ่มมากขึ้น $x\mapsto H(G(x))$สร้างขึ้นโดยใช้ bijection เสริมแบบสุ่มหลอก $G$, เช่น. $G(x)=G_2(G_1(G_0(x)))$ กับ $G_i(x)=k_i(x\oplus(x\gg\lceil b/3+1\rceil))\bmod2^b$ สำหรับ $k_i$ จับจด แปลก $ข$- ค่าคงที่บิต [โดยที่ $\gg$ เป็นกะขวาและ $ข$ คือขนาดบิตของ $x$]. เมื่อเกิดการชนกัน $x,x'$ พบกับ $H(G(x))=H(G(x'))$ แต่ $x\ne x'$, การชนกันเพื่อ $H$ เป็น $ก(x),ก(x')$.


ข้อดีประการหนึ่งของการค้นหาการชนกันของ Pollard's rho ที่มีจุดแตกต่าง (แทนที่จะเป็นวิธีการในรหัสของคำถาม) คือลักษณะการวนซ้ำมักจะแก้ปัญหาของฟังก์ชันสุ่มที่ไม่เพียงพอซึ่งค้นหาการชนกันโดยไม่มีตัวช่วย $G$; หรือค่อนข้างง่าย $G$ จะทำ (ที่นี่ฉันคิดว่าการหมุน 1 บิตในข้อเสนอแนะของ Pollard's rho ควรทำเพื่อชดเชยการขาดการแพร่กระจายที่ถูกต้อง) นอกจากนี้ โรของพอลลาร์ดยังใช้หน่วยความจำน้อยกว่า ดังนั้นจึงใช้ได้กับแฮชที่ใหญ่ขึ้น และสำหรับฟังก์ชันแฮชที่รวดเร็ว ก็ยิ่งเร็วขึ้นเนื่องจากเป็นมิตรกับแคช

kodlu avatar
sa flag
ดี. มีเหตุผลเชิงพีชคณิตเชิงลึกในแฮชที่เกี่ยวข้องกับ MD5 ของคุณที่ขัดแย้งกันสำหรับค่าจำนวนเต็มตามลำดับหรือไม่ นอกเหนือจาก 263 ที่ค่อนข้างเฉพาะสำหรับโมดูลัสที่เกี่ยวข้อง? ไม่สามารถบอกได้อย่างรวดเร็ว
Reppiz avatar
gb flag
โดยส่วนตัวแล้วฉันไม่ค่อยเข้าใจว่าทำไมการแก้ไข G จึงทำงานตามลำดับ มีคำอธิบายเพิ่มเติม (หรือเชิงลึกมากกว่านี้) หรือไม่ ลิงก์ไปยังกระดาษ บล็อก บทความ ฯลฯ ... ซึ่งวิธีนี้จะอธิบายด้วยวิธีใดวิธีหนึ่ง
fgrieu avatar
ng flag
@Reppiz: ตอนนี้ฉันพยายามให้เหตุผล โดยพื้นฐานแล้ว หากเรามีปัญหากับ $H$ เนื่องจากมันไม่สุ่มเพียงพอ เราจะทำให้มันสุ่มมากขึ้นโดยแนะนำ $G$
fgrieu avatar
ng flag
@Meir Maor: อย่าลืมอ่านบทนำใหม่!
Meir Maor avatar
in flag
ใช่ ฉันกังวลเกี่ยวกับเรื่องนี้ และนี่กำลังกลายเป็นคำตอบที่ยอดเยี่ยมจริงๆ มีข้อบกพร่องหลายประการในความพยายามของฉัน แต่ความสำเร็จของฉันในการค้นหาการชนที่ใกล้ (ค่อนข้างน้อยแต่ไม่น้อยไปกว่า) อัตราที่คาดไว้ทำให้ฉันผิดหวัง
Score:2
ธง cn

ไม่กล้าแสดงความคิดเห็น...

ฉันคาดว่ามันเป็นปัญหาการใช้งาน - คำอธิบายระดับสูงของวิธีการนั้นดูสมเหตุสมผล สามารถค้นหาการชนกันได้หรือไม่หากคุณใช้คำนำหน้าแทน 0x01000099 และ 0xDEADBD5C?

สปอยเลอร์: เช่น. 0x010000992287FF50 กับ 0xDEADBD5C05F19159

วิธีการที่ใช้ในการค้นหาการชนกันนี้เป็นหลักเหมือนกับที่คุณอธิบาย ยกเว้นว่าฉันจะใช้วิธีนั้นหากเราสามารถค้นหาการชนกันของ 56 ไบต์ที่สำคัญที่สุดของแฮช (หรือในทางเทคนิค แฮชที่ไม่มีค่าสุดท้าย การประยุกต์ใช้ f) มันเป็นเรื่องเล็กน้อยที่จะขยายลำดับไบต์ทีละหนึ่งไบต์เพื่อให้ได้การชนกันแบบเต็ม (64 บิต)

fgrieu avatar
ng flag
ดูเหมือนว่าถูกต้องตามกฎหมายเป็นคำตอบ (แทนที่จะแสดงความคิดเห็น) สำหรับฉันแม้ว่าจะตอบว่า "ทำไมไม่พบการชนกัน" โดย "ควรมี"; และฉันมีคำอธิบายอื่น
Meir Maor avatar
in flag
เนื้อเรื่องหนาขึ้นด้วยคำนำหน้าเหล่านี้รหัสของฉันพบว่า 65 ใกล้ชนกันและ 64 ในนั้นกลายเป็นชนกันเต็ม ในฟังก์ชั่นที่สมบูรณ์แบบฉันคาดว่าจะพบการชนกันเพียงครั้งเดียวในแต่ละคู่คำนำหน้า (เพราะฉันเก็บเพียง 1/4 ของค่าที่แฮชในคำนำหน้าแรก)
Maarten Bodewes avatar
in flag
มี mod 127 หรือคล้ายกันไหม

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา