पायथन 3.3 में हैश फ़ंक्शन सत्रों के बीच अलग-अलग परिणाम देता है


97

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

उदाहरण:

>>> hash("235")
-310569535015251310

----- एक नया अजगर कंसोल खोलने -----

>>> hash("235")
-1900164331622581997

ये क्यों हो रहा है? यह क्यों उपयोगी है?

जवाबों:


136

पायथन हमलावरों को टकराने से रोकने के लिए एक यादृच्छिक हैश बीज का उपयोग करता है ताकि आप टकराने के लिए डिज़ाइन की गई चाबियों को भेजकर अपने आवेदन को रोक सकें। मूल भेद्यता प्रकटीकरण देखें । एक यादृच्छिक बीज (स्टार्टअप पर एक बार सेट) के साथ हैश को ऑफसेट करके हमलावर अब अनुमान नहीं लगा सकते हैं कि चाबियाँ क्या टकराएंगी।

आप एक निश्चित बीज सेट कर सकते हैं या PYTHONHASHSEEDपर्यावरण चर सेट करके सुविधा को अक्षम कर सकते हैं ; डिफ़ॉल्ट है, randomलेकिन आप 0पूरी तरह से सुविधा को अक्षम करने के साथ, इसे एक निश्चित सकारात्मक पूर्णांक मान पर सेट कर सकते हैं।

पायथन संस्करण 2.7 और 3.2 में डिफ़ॉल्ट रूप से अक्षम सुविधा है ( इसे सक्षम करने के लिए -Rस्विच या सेट PYTHONHASHSEED=randomका उपयोग करें); यह Python 3.3 और उसके बाद डिफ़ॉल्ट रूप से सक्षम है।

यदि आप पायथन सेट में चाबियों के क्रम पर भरोसा कर रहे हैं, तो नहीं। पायथन इन प्रकारों को लागू करने के लिए एक हैश तालिका का उपयोग करता है और उनका क्रम सम्मिलन और विलोपन इतिहास के साथ-साथ यादृच्छिक हैश बीज पर निर्भर करता है । ध्यान दें कि पायथन 3.5 और पुराने में, यह शब्दकोशों पर भी लागू होता है।

object.__hash__()विशेष विधि प्रलेखन भी देखें :

नोट : डिफ़ॉल्ट रूप से, __hash__()str, बाइट्स और डेटाइम ऑब्जेक्ट्स के मान एक अप्रत्याशित यादृच्छिक मूल्य के साथ "नमकीन" हैं। यद्यपि वे एक व्यक्तिगत पायथन प्रक्रिया के भीतर स्थिर रहते हैं, वे पायथन के बार-बार होने वाले आक्रमणों के बीच अनुमानित नहीं हैं।

इसका उद्देश्य सावधानी से चुने गए इनपुट के कारण एक इनकार-सेवा के खिलाफ सुरक्षा प्रदान करना है जो एक तानाशाही प्रविष्टि, ओ (एन ^ 2) जटिलता के सबसे खराब मामले के प्रदर्शन का फायदा उठाते हैं। देखें http://www.ocert.org/advisories/ocert-2011-003.html जानकारी के लिए।

हैश मानों को बदलने से dicts, सेट और अन्य मैपिंग के पुनरावृति क्रम प्रभावित होते हैं। पायथन ने इस आदेश के बारे में कभी गारंटी नहीं दी है (और यह आमतौर पर 32-बिट और 64-बिट बिल्ड के बीच भिन्न होता है)।

यह भी देखें PYTHONHASHSEED

यदि आपको एक स्थिर हैश कार्यान्वयन की आवश्यकता है, तो आप संभवतः hashlibमॉड्यूल को देखना चाहते हैं ; यह क्रिप्टोग्राफ़िक हैश फ़ंक्शन को कार्यान्वित करता है। Pybloom परियोजना इस दृष्टिकोण का उपयोग करता है

चूंकि ऑफसेट में एक उपसर्ग और एक प्रत्यय होता है (प्रारंभ मूल्य और क्रमशः अंतिम XORed मूल्य,) आप ऑफसेट को स्टोर नहीं कर सकते, दुर्भाग्य से। प्लस साइड पर, इसका मतलब है कि हमलावर आसानी से समय के हमलों के साथ ऑफसेट का निर्धारण नहीं कर सकते हैं।


9
मुझे उम्मीद है कि यह हैश () डॉक्स में और __हाश __ () में नहीं दिखाएगा। एक महान जवाब के लिए +1। PS हैश फ़ंक्शन के गैर-क्रिप्टोग्राफ़िक उपयोगों के लिए हैशलीब एक ओवरकिल नहीं है?
रिड्यूस करें

1
pybloom hashlib फ़ंक्शंस का उपयोग करता है। लेकिन अगर आप कुछ तेज चाहते हैं, तो आप pyhash की जांच कर सकते हैं ।
होकेन लिड

3
disableइसे 0 पर सेट करने पर दस्तावेज़ीकरण इसे क्यों कहता है ? जब तक मैं कुछ याद नहीं कर रहा हूं, मुझे किसी भी पुराने स्थिर बीज संख्या में इसे स्थापित करने के लिए प्रभावी अंतर नहीं दिखता है। जब मैं उपयोग करता PYTHONHASHSEED=12345हूं तो मेरा मतलब है कि मैं सत्रों के दौरान भी समान स्ट्रिंग्स के लिए समान हैश प्राप्त करता हूं - वही तब होता है जब मैं उपयोग करता हूं PYTHONHASHSEED=0- समान स्ट्रिंग्स के लिए हैश पूरे सत्रों के लिए समान होगा (यद्यपि 12345 के लिए अलग-अलग, लेकिन यह स्पष्ट है कि बीज कैसे है काम)।
ब्लबरडाइब्लूब

@blubberdiblub: 0इसमें कोई बीज नहीं है और वस्तुओं के लिए हैश बिना किसी हैशड सपोर्ट के एक पुराने पायथन संस्करण में उत्पन्न हुए लोगों के बराबर हैं।
मार्टिन पीटर्स

1
@MartijnPieters प्रभावित हैश के लिए "कोई बीज नहीं" होने का क्या मतलब है? 12345 के बीज के बारे में कहने के लिए शब्दार्थ या गुणात्मक अंतर क्या है, इस तथ्य के अलावा कि यह सत्रों के दो अलग-अलग सेट बनाता है जिसके बीच हैश मान भिन्न होते हैं और इसके अलावा PYTHONHASHSEED = 0 पुराने संस्करणों के बराबर है? क्या आप मुझे किसी विशेष स्रोत कोड से जोड़ सकते हैं? मुझे लगता है कि मेरी बात यह है कि यदि ऐसा कोई अंतर नहीं है, तो मैं इसे 0 के बीज और पुराने संस्करणों को केवल 0. के बीज का समर्थन करने वाला कहूंगा। यह अभी मेरे लिए काफी दस्तावेजी है।
ब्लबरडाइब्लूब

10

पायथन 3 में डिफ़ॉल्ट रूप से हैश रैंडमाइजेशन चालू है । यह एक सुरक्षा विशेषता है:

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

2.6.8 से पिछले संस्करणों में, आप इसे -R या PYTHONHASHSEED पर्यावरण विकल्प के साथ कमांड लाइन पर स्विच कर सकते हैं ।

आप इसे PYTHONHASHSEEDशून्य पर सेट करके स्विच कर सकते हैं ।


-9

हैश () एक पायथन बिल्ट-इन फ़ंक्शन है और इसका उपयोग ऑब्जेक्ट के लिए हैश मान की गणना करने के लिए किया जाता है , स्ट्रिंग या संख्या के लिए नहीं।

आप इस पृष्ठ का विवरण देख सकते हैं: https://docs.python.org/3.3/library/functions.html#hash

और हैश () मान ऑब्जेक्ट की __hash__ विधि से आता है। डॉक्टर कहते हैं कि अनुसरण:

डिफ़ॉल्ट रूप से, str, बाइट्स और डेटाइम ऑब्जेक्ट्स के हैश () मान एक अप्रत्याशित यादृच्छिक मूल्य के साथ "नमकीन" होते हैं। यद्यपि वे एक व्यक्तिगत पायथन प्रक्रिया के भीतर स्थिर रहते हैं, वे पायथन के बार-बार होने वाले आक्रमणों के बीच अनुमानित नहीं हैं।

यही कारण है कि आपके पास अलग-अलग कंसोल में एक ही स्ट्रिंग के लिए हैश मान है।

आप जो लागू करते हैं वह एक अच्छा तरीका नहीं है।

जब आप एक स्ट्रिंग हैश मान की गणना करना चाहते हैं, तो बस हैशलीब का उपयोग करें

हैश () का उद्देश्य एक वस्तु हैश मूल्य प्राप्त करना है, न कि कोई हलचल।


6
hash()स्ट्रिंग या संख्यात्मक मानों के लिए पूरी तरह से मान्य है। आप इसे __hash__कस्टम विधि के साथ भ्रमित कर रहे हैं , जिसका उपयोग हैश मूल्य के कस्टम कार्यान्वयन प्रदान करने के लिए किया जाता हैhash()
मार्टिन पीटर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.