ทำไม std :: hash ไม่รับประกันว่าจะถูกกำหนดขึ้น?


28

หลังจากนี้เราใช้N4140 (มาตรฐาน C ++ 14)


ตาม§ 17.6.3.4 ต้องการแฮ ,

ค่าที่ส่งคืนจะขึ้นอยู่กับอาร์กิวเมนต์k ในช่วงเวลาของโปรแกรมเท่านั้น

[หมายเหตุ: ดังนั้นการประเมินผลทั้งหมดของการแสดงออกh(k)ที่มีค่าเหมือนกันสำหรับ kผลผลิตผลเดียวกันสำหรับการดำเนินการที่กำหนดของโปรแกรม - บันทึกท้าย]

และแฮชของเทมเพลตคลาส Class 20.9.12พูดว่า

...

การเริ่มต้นhash<Key>จะต้อง:

(1.1) - ตอบสนองความต้องการของแฮช (17.6.3.4) ...

(1.2) - ...


ซึ่งหมายความว่าค่าแฮชของvalue(เช่นhash<decltype(value)>(value)) อาจใช้ค่าอื่นหากคุณรีสตาร์ทโปรแกรม

แต่ทำไม ข้อ จำกัด นี้ไม่ได้อยู่ในมาตรฐานของ C ++ 11 แต่อยู่ในมาตรฐานของ C ++ 14, C ++ 17 และ C ++ 20 ในฐานะผู้ใช้ (ไม่ใช่นักพัฒนา STL) มันจะค่อนข้างมีประโยชน์หากstd::hashกำหนดไว้ มีปัญหาทางคณิตศาสตร์ในการใช้ฟังก์ชันแฮชที่กำหนดขึ้นได้หรือไม่? แต่ฟังก์ชันแฮชที่เราใช้ในชีวิตประจำวัน (เช่นเลิกใช้md5sumหรือปลอดภัยกว่าsha256) ล้วนแล้วแต่กำหนดไว้แล้ว มีปัญหาเรื่องประสิทธิภาพหรือไม่?


7
"... ต้องใช้ฟังก์ชันแฮชเพื่อสร้างผลลัพธ์เดียวกันสำหรับอินพุตเดียวกันภายในการประมวลผลโปรแกรมเดียวซึ่งจะช่วยให้แฮชเค็มที่ป้องกันการโจมตีแบบปฏิเสธการให้บริการ " แหล่งที่มา: en.cppreference.com/w/cpp/utility/hash
Richard Critten

5
อนุญาตให้อัลกอริธึมที่กำหนดขึ้นเพื่อรับอินพุตที่ไม่ได้กำหนดไว้ ค่าตัวชี้ตัวอย่างเช่น โครงสร้างข้อมูลที่ไม่เปลี่ยนรูปอาจทำให้ที่อยู่ของข้อมูลภายในของแฮชซึ่งอาจเร็วกว่าการแฮชเนื้อหา
John Kugelman

4
คำตอบนี้มีลิงก์ที่ดีสำหรับเหตุผลที่คุณไม่ต้องการกำหนด
NathanOliver

3
อย่าคุกคามข้อ จำกัด นี้ แต่ทำให้ข้อ จำกัด มาตรฐานเข้มงวดน้อยลงเล็กน้อย
Marek R

4
นี่คือคำอธิบายแบบเต็มว่าทำไมข้อ จำกัด คลายขึ้น
Marek R

คำตอบ:


17

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

สำหรับเหตุผลcppreferenceพูดว่า:

ฟังก์ชันแฮชจะต้องสร้างผลลัพธ์เดียวกันสำหรับอินพุตเดียวกันภายในการประมวลผลโปรแกรมเดียว สิ่งนี้จะช่วยให้แฮ็คเค็มที่ป้องกันการโจมตีปฏิเสธการบริการ

หากHashข้อกำหนดบอกว่าเป็นสิ่งที่กำหนดได้คุณจะไม่สามารถให้กัญชาที่ใส่เกลือได้โดยไม่ทำลายข้อกำหนด

นี่คือคำอธิบายที่แท้จริงว่าทำไม


7

คำตอบนี้ (และลิงก์ใน) แนะนำโดย@NathanOliverในที่สุดจะเป็นประโยชน์ ให้ฉันอ้างอิงส่วนที่สำคัญ

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

(จากฉบับที่ 2291 std :: hash มีความเสี่ยงต่อการชนกันของการโจมตี DoS )

ด้วยเหตุนี้นักออกแบบภาษาจึงย้ายไปยังการแฮ็กแบบสุ่ม ในการแฮ็กแบบสุ่มค่าแฮชของสตริง“ a” สามารถเปลี่ยนได้ทุกครั้งที่คุณเรียกใช้โปรแกรม การแฮ็ชแบบสุ่มเป็นค่าเริ่มต้นใน Python (ตั้งแต่รุ่น 3.3), Ruby (ตั้งแต่รุ่น 1.9) และ Perl (ตั้งแต่รุ่น 5.18)

(จากคุณทราบหรือไม่ว่าคุณกำลังใช้การแฮ็กแบบสุ่ม )

ย้ายไปที่พร้อมแล้วมากกว่าทันทีเพราะแม้แต่การขออนุญาตก็ยังเป็นที่ถกเถียงกันในการอภิปรายของตัวสะท้อนสัญญาณ

(จากฉบับที่ 2291 std :: hash มีความเสี่ยงต่อการชนกันของการโจมตี DoS )

ในทางปฏิบัติเท่าที่ฉันเข้าใจไม่มีการstd::hashใช้งานการแฮ็กแบบสุ่ม แต่คุณสามารถเขียนของคุณเองmy::secure_hashได้

(จากคำตอบนี้ )


PS

ฉันเพียงแค่ googled "ดอสตารางแฮช" และพบหน้าข้อมูล: ขณะที่เมื่อคุณตระหนักเซิร์ฟเวอร์ทุกคนในโลกมีความเสี่ยง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.