2012-04-26 12 views
15

मैं एक ऐसे प्रोजेक्ट पर काम कर रहा हूं जहां एक यादृच्छिक हैश उत्पन्न करने की आवश्यकता है। हमारे पास चर्चा करने का समय होने से पहले, हम दोनों अलग-अलग दृष्टिकोणों के साथ आए और क्योंकि वे विभिन्न मॉड्यूल का उपयोग कर रहे हैं, मैं आपसे पूछना चाहता हूं कि क्या बेहतर होगा - अगर ऐसी कोई चीज है।क्या अधिक यादृच्छिक, हैशिलब या यूरैंडम?

hashlib.sha1(str(random.random())).hexdigest() 

या

os.urandom(16).encode('hex') 

इस सवाल को लिखकर मुझे यह सोच कर कि दूसरी विधि बेहतर है मिल गया है। सरल जटिल से बेहतर है। यदि आप सहमत हैं, 'यादृच्छिक रूप से' उत्पन्न करने वाले हैंश के लिए यह कितना विश्वसनीय है? मैं इसका परीक्षण कैसे करूं?

उत्तर

36

यह समाधान:

os.urandom(16).encode('hex') 

के बाद से यह uses the OS अनियमितता जो क्रिप्टोग्राफिक प्रयोजनों के लिए प्रयोग करने योग्य होना चाहिए (ओएस कार्यान्वयन पर निर्भर करता है) उत्पन्न करने के लिए सबसे अच्छा है।

random.random()pseudo-random values उत्पन्न करता है।

यादृच्छिक मूल्य को धक्का देना कोई नई यादृच्छिकता नहीं जोड़ता है।

+0

का उपयोग करना चाहिए ये सब वास्तव में महान उत्तर दिए गए हैं। धन्यवाद। – Flowpoke

+0

विशेषताएँ: 'बाइट्स' ऑब्जेक्ट में कोई विशेषता नहीं है 'एन्कोड' – treecoder

+0

@greengit: संभावनाएं हैं (बहुत अधिक) कि ऊपर छोटा स्निपेट पाइथन 2.x संस्करण (3.x में अनचाहे) – ChristopheD

2

यादृच्छिकता का परीक्षण कुख्यात रूप से कठिन है - हालांकि, मैं इस मामले के लिए दूसरी विधि का चयन करता हूं, लेकिन केवल (या, केवल दिमाग में आता है), जहां हैश को यादृच्छिक संख्या से बीजित किया जाता है।

हैश के पूरे मुद्दे एक संख्या है कि है एकदम अलग इनपुट में मामूली अंतर के आधार पर तैयार करना है। आपके उपयोग के मामले में, इनपुट की यादृच्छिकता करना चाहिए। यदि, हालांकि, आप एक फ़ाइल हैश करना चाहते हैं और एक ईन्सी बाइट के अंतर का पता लगाना चाहते हैं, तब वह हैश एल्गोरिदम चमकता है।

मैं सिर्फ उत्सुक हूं, हालांकि: हैश एल्गोरिदम का उपयोग क्यों करें? ऐसा लगता है कि आप पूरी तरह यादृच्छिक संख्या की तलाश में हैं, और ऐसे कई पुस्तकालय हैं जो यूयूआईडी उत्पन्न करते हैं, जिनके पास यादृच्छिक संख्या जेनरेटर की तुलना में विशिष्टता की बहुत मजबूत गारंटी है।

7

random.random() एक छद्म-रेडमोम जनरेटर है, जिसका अर्थ है कि संख्या अनुक्रम से उत्पन्न होती है। यदि आप random.seed(some_number) पर कॉल करते हैं, तो उसके बाद जेनरेट अनुक्रम हमेशा एक जैसा होगा।

os.urandom() प्राप्त ओएस 'RNG, जो असली यादृच्छिक संख्या, आमतौर पर हार्डवेयर उपकरणों से यादृच्छिक घटनाओं से इकट्ठा करने के लिए एक एन्ट्रापी पूल का उपयोग करता है से यादृच्छिक संख्या है, वहाँ प्रणालियों जहां यादृच्छिक संख्या के एक बहुत हैं के लिए भी यादृच्छिक विशेष एन्ट्रापी जनरेटर मौजूद उत्पन्न।

यूनिक्स सिस्टम पर परंपरागत रूप से दो यादृच्छिक संख्या जनरेटर हैं: /dev/random और /dev/urandom। यदि पर्याप्त एंट्रॉपी उपलब्ध नहीं है, तो पहले ब्लॉक पर कॉल करें, जबकि जब आप /dev/urandom पढ़ते हैं और पर्याप्त एन्ट्रॉपी डेटा उपलब्ध नहीं है, तो यह एक छद्म-आरएनजी का उपयोग करता है और ब्लॉक नहीं करता है।

इसलिए उपयोग आमतौर पर आपको जो चाहिए उसे निर्भर करता है: यदि आपको कुछ, समान रूप से वितरित यादृच्छिक संख्याओं की आवश्यकता होती है, तो अंतर्निहित prng पर्याप्त होना चाहिए। क्रिप्टोग्राफिक उपयोग के लिए वास्तविक यादृच्छिक संख्याओं का उपयोग करना हमेशा बेहतर होता है।

7

दूसरा समाधान स्पष्ट रूप से पहले की तुलना में अधिक एन्ट्रॉपी है।यादृच्छिक बिट्स के स्रोत की गुणवत्ता मान लिया जाये कि os.urandom और random.random के लिए एक ही होगा:

  • दूसरा समाधान आप 16 बाइट्स = अनियमितता
  • की कीमत 128 बिट फ़ेच कर रहे हैं पहला समाधान आप फ़ेच कर रहे हैं में एक फ्लोटिंग प्वाइंट वैल्यू जिसमें लगभग 52 बिट्स यादृच्छिकता है (आईईईई 754 डबल, असामान्य संख्याओं को अनदेखा कर रहा है ...)। फिर आप इसे चारों ओर हैश, जो, निश्चित रूप से, कोई यादृच्छिकता नहीं जोड़ता है।

इससे भी महत्वपूर्ण बात, अनियमितता os.urandom से आने वाले की गुणवत्ता की उम्मीद है और अनियमितता random.random से आने वाले की तुलना में बेहतर होने के लिए दर्ज है। os.urandom का डॉक्स्टिंग कहता है "क्रिप्टोग्राफिक उपयोग के लिए उपयुक्त"।