मुझे पहले से माफी मांगनी चाहिए, क्योंकि यह समझना थोड़ा कठिन है ...
सबसे पहले, आप पहले से ही जानते हैं कि java.util.Random
पूरी तरह से यादृच्छिक नहीं है। यह बीज से पूरी तरह से अनुमानित तरीके से अनुक्रम उत्पन्न करता है। आप पूरी तरह से सही हैं कि, क्योंकि बीज केवल 64 बिट लंबा है, यह केवल 2 ^ 64 विभिन्न अनुक्रम उत्पन्न कर सकता है। यदि आप किसी तरह 64 वास्तविक यादृच्छिक बिट्स उत्पन्न करते हैं और एक बीज का चयन करने के लिए उनका उपयोग करते हैं, तो आप उस बीज का उपयोग 52 के सभी के बीच बेतरतीब ढंग से चुनने के लिए नहीं कर सकते हैं ! समान संभावना के साथ संभव अनुक्रम।
हालाँकि, इस तथ्य का कोई परिणाम नहीं है जब तक आप वास्तव में 2 ^ 64 से अधिक अनुक्रम उत्पन्न करने वाले नहीं हैं, जब तक कि 2 ^ 64 अनुक्रमों के बारे में 'विशेष' या 'विशेष रूप से विशेष' कुछ भी नहीं है जो इसे उत्पन्न कर सकता है ।
कहते हैं कि आपके पास बहुत बेहतर PRNG था जो 1000-बिट बीजों का उपयोग करता था। कल्पना कीजिए कि आपके पास इसे आरंभ करने के दो तरीके हैं - एक तरीका यह है कि इसे पूरे बीज का उपयोग करके आरंभ किया जाएगा, और एक तरीका यह होगा कि बीज को प्रारंभिक करने से पहले 64 बिट तक नीचे ले जाया जाए।
अगर आपको पता नहीं था कि कौन सा इनिशलाइज़र था, तो क्या आप उन्हें भेद करने के लिए किसी भी तरह का टेस्ट लिख सकते थे? जब तक आप (संयुक्त राष्ट्र) भाग्यशाली नहीं थे, तब तक बुरे को एक ही 64 बिट्स के साथ दो बार समाप्त करने के लिए , फिर जवाब नहीं है। आप विशिष्ट PRNG कार्यान्वयन में कुछ कमजोरियों के बारे में विस्तृत जानकारी के बिना दो शुरुआती के बीच अंतर नहीं कर सकते।
वैकल्पिक रूप से, कल्पना करें कि Random
वर्ग में 2 ^ 64 अनुक्रमों की एक सरणी थी जो कि किसी भी समय दूर के अतीत में पूरी तरह से और यादृच्छिक रूप से चुनी गई थी, और यह कि बीज इस सरणी में सिर्फ एक सूचकांक था।
तो यह तथ्य कि Random
इसके बीज के लिए केवल 64 बिट्स का उपयोग किया जाता है, वास्तव में जरूरी नहीं कि यह एक समस्या है, जब तक कि कोई महत्वपूर्ण मौका नहीं है कि आप एक ही बीज का दो बार उपयोग करेंगे।
बेशक, क्रिप्टोग्राफिक प्रयोजनों के लिए, एक 64 बिट बीज पर्याप्त नहीं है, क्योंकि एक ही बीज का दो बार उपयोग करने के लिए एक प्रणाली प्राप्त करना कम्प्यूटेशनल रूप से संभव है।
संपादित करें:
मुझे यह जोड़ना चाहिए, भले ही उपरोक्त सभी सही हो, कि वास्तविक कार्यान्वयन java.util.Random
भयानक नहीं है। यदि आप कार्ड गेम लिख रहे हैं, तो शायद MessageDigest
SHA-256 हैश उत्पन्न करने के लिए API का "MyGameName"+System.currentTimeMillis()
उपयोग करें, और उन बिट्स का उपयोग डेक को फेरबदल करने के लिए करें। उपरोक्त तर्क के अनुसार, जब तक आपके उपयोगकर्ता वास्तव में जुआ नहीं कर रहे हैं, आपको चिंता करने की ज़रूरत नहीं है कि currentTimeMillis
एक लंबा रिटर्न देता है। यदि आपके उपयोगकर्ता वास्तव में जुआ कर रहे हैं , तो SecureRandom
बिना बीज के उपयोग करें ।
Random
कभी भी वास्तविक यादृच्छिक संख्या नहीं होती है। यह एक PRNG है, जहां P "छद्म" के लिए खड़ा है। के लिए असली यादृच्छिक संख्या, आप अनियमितता (जैसे random.org के रूप में) का एक स्रोत की जरूरत है।