क्यों std :: hash नियतात्मक होने की गारंटी नहीं है?


28

इसके बाद, हम N4140 (C ++ 14 स्टैंडर्ड) का उपयोग करते हैं।


के अनुसार 17.6.3.4 हैश आवश्यकताओं § ,

लौटाया गया मान केवल k कार्यक्रम की अवधि के लिए तर्क पर निर्भर करेगा ।

[नोट: इस प्रकार कार्यक्रम के दिए गए निष्पादन के लिए समान परिणाम प्राप्त करने के लिए एकh(k) ही मूल्य के साथ अभिव्यक्ति के सभी मूल्यांकन । - अंतिम नोट]k

और § 20.9.12 क्लास टेम्पलेट हैश कहता है

...

तात्कालिकता hash<Key>होगी:

(१.१) - हैश आवश्यकताओं को संतुष्ट करें (१ ).६.३.४) ...

(१.२) - ...


इसका मतलब है कि हैश मान value(यानी hash<decltype(value)>(value)) यदि आप प्रोग्राम को पुनरारंभ करते हैं तो एक अलग मान ले सकते हैं।

लेकिन क्यों? यह सीमा C ++ 11 के मानक में नहीं थी, लेकिन C ++ 14, C ++ 17 और C ++ 20 के मानक में थी। एक उपयोगकर्ता (एसटीएल डेवलपर नहीं) के रूप में, यह काफी उपयोगी होगा यदि std::hashयह निर्धारक हो। क्या नियतात्मक हैश फ़ंक्शन को लागू करने में कोई गणितीय कठिनाइयाँ हैं? लेकिन हैश फ़ंक्शन हम दैनिक उपयोग करते हैं (जैसे पदावनत md5sumया सुरक्षित sha256) सभी नियतात्मक हैं। क्या दक्षता की समस्या है?


7
"... हैश फ़ंक्शन को प्रोग्राम के एकल निष्पादन के भीतर एक ही इनपुट के लिए एक ही परिणाम का उत्पादन करने की आवश्यकता होती है; यह नमकीन हैश को टकराव से बचाने वाली सेवा हमलों को रोकने की अनुमति देता है ।" स्रोत: en.cppreference.com/w/cpp/utility/hash
रिचर्ड क्रिट

5
यह निर्धारक एल्गोरिथ्म को गैर-नियतात्मक इनपुट लेने की अनुमति देता है। उदाहरण के लिए, पॉइंटर मान। एक अपरिवर्तनीय डेटा संरचना अपने आंतरिक डेटा के पते को हैश कर सकती है, जो सामग्री को हैशिंग से बहुत तेज कर सकता है।
जॉन कुगेलमैन

4
इस उत्तर के लिए कुछ अच्छे लिंक हैं कि आप नियतत्ववाद क्यों नहीं चाहते हैं।
नेथनऑलिवर

3
इसे सीमा के रूप में खतरे में न डालें, लेकिन मानक बनाने से थोड़ी सख्ती होती है।
मारेक आर

4
यहाँ पूरी व्याख्या है कि बाधाओं को क्यों ढीला किया गया है।
मारेक आर

जवाबों:


17

रनों के बीच हैश फ़ंक्शन के लिए नियतात्मक होने की कोई आवश्यकता नहीं है, लेकिन आप अभी भी अपने स्वयं के हैश प्रदान कर सकते हैं, जैसे कि अनियंत्रित कंटेनरों के लिए यदि यह एक ऐसा व्यवहार है जिस पर आप भरोसा करते हैं।

क्यों के लिए, cppreference कहते हैं:

हैश फ़ंक्शन को केवल एक प्रोग्राम के एकल निष्पादन के भीतर एक ही इनपुट के लिए एक ही परिणाम का उत्पादन करने की आवश्यकता होती है; यह नमकीन हैश की अनुमति देता है जो टकराव से इनकार करता है सेवा के हमलों।

यदि Hashआवश्यकताएँ इसे नियतात्मक बताती हैं, तो आप आवश्यकता को तोड़े बिना नमकीन हैश प्रदान नहीं कर पाएंगे।

यहाँ वास्तविक स्पष्टीकरण क्यों है


7

@NathanOliver द्वारा सुझाया गया यह उत्तर (और इसमें लिंक) अंततः मददगार है। मुझे महत्वपूर्ण भागों का हवाला देते हैं।

एक गैर-क्रिप्टोग्राफ़िक हैश फ़ंक्शन के लिए, एक ही हैशेड मान के साथ बड़े पैमाने पर इनपुट की पूर्व-गणना करना संभव है जो कि अनियंत्रित कंटेनरों को धीमा कर देता है, और एक इनकार-में-सेवा हमले का परिणाम है।

( अंक 2291 से। std :: हैश टकराव की चपेट में है )

इस कारण से, भाषा डिजाइनर यादृच्छिक हैशिंग की ओर पलायन कर रहे हैं। यादृच्छिक हैशिंग में, स्ट्रिंग का हैश मान "a" हर बार जब आप अपना प्रोग्राम चलाते हैं, बदल सकते हैं। रैंडम हैशिंग अब पायथन (संस्करण 3.3 के रूप में), रूबी (संस्करण 1.9 के रूप में) और पर्ल (संस्करण 5.18 के रूप में) में डिफ़ॉल्ट है।

( क्या आपको एहसास है कि आप यादृच्छिक हैशिंग का उपयोग कर रहे हैं? )

इमीडिएट के बजाय रेडी की ओर कदम बढ़ाएं, क्योंकि यहां तक ​​कि अनुमति रिफ्लेक्टर चर्चा में भी विवादास्पद रही है

( अंक 2291 से। std :: हैश टकराव की चपेट में है )

व्यवहार में, जहाँ तक मैं समझता हूँ, std::hashयादृच्छिक हैशिंग के क्रियान्वयन का कोई कार्यान्वयन नहीं है लेकिन आप अपना स्वयं का लिख ​​सकते हैं my::secure_hash

( इस जवाब से )


पुनश्च

मैंने सिर्फ "हैश टेबल डॉस" को गुमराह किया और एक सूचनात्मक पेज पाया: वह क्षण जब आपको दुनिया के हर सर्वर का एहसास होता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.