मुझे पता है कि यादृच्छिक UUIDs के सिद्धांत में टकराव के लिए बहुत, बहुत कम संभावना है, लेकिन मैं सोच रहा हूं, व्यवहार में, randomUUID()
टक्कर नहीं होने के मामले में जावा कितना अच्छा है? क्या किसी को साझा करने का कोई अनुभव है?
मुझे पता है कि यादृच्छिक UUIDs के सिद्धांत में टकराव के लिए बहुत, बहुत कम संभावना है, लेकिन मैं सोच रहा हूं, व्यवहार में, randomUUID()
टक्कर नहीं होने के मामले में जावा कितना अच्छा है? क्या किसी को साझा करने का कोई अनुभव है?
जवाबों:
यूयूआईडी का उपयोग करता है java.security.SecureRandom
, जिसे "क्रिप्टोग्राफिक रूप से मजबूत" माना जाता है। हालांकि वास्तविक कार्यान्वयन निर्दिष्ट नहीं है और जेवीएम के बीच भिन्न हो सकता है (जिसका अर्थ है कि किए गए किसी भी ठोस बयान केवल एक विशिष्ट जेवीएम के लिए मान्य हैं), यह अनिवार्य है कि आउटपुट को एक सांख्यिकीय यादृच्छिक संख्या जनरेटर परीक्षण पास करना होगा।
एक कार्यान्वयन के लिए यह हमेशा संभव है कि इसमें सूक्ष्म कीड़े शामिल हों जो यह सब बर्बाद करते हैं (ओपनएसएसएच कुंजी पीढ़ी बग देखें) लेकिन मुझे नहीं लगता कि जावा यूयूआईडीएस की यादृच्छिकता के बारे में चिंता करने का कोई ठोस कारण है।
विकिपीडिया का बहुत अच्छा जवाब है http://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions
यादृच्छिक संस्करण 4 यूयूआईडी की संख्या जिसे उत्पन्न करने की आवश्यकता है ताकि कम से कम एक टक्कर की 50% संभावना हो 2.71 क्विंटल, इस प्रकार गणना की गई है:
...
यह संख्या लगभग 85 वर्षों के लिए 1 बिलियन यूयूआईडी प्रति सेकंड उत्पन्न करने के बराबर है, और इस फाइल में कई यूयूआईडी हैं, जिसमें 16 बाइट्स प्रति यूयूआईडी हैं, लगभग 45 एक्साबाइट होंगे, जो वर्तमान में अस्तित्व में सबसे बड़े डेटाबेस से कई गुना बड़ा है, जो चालू हैं सैकड़ों पेटाबाइट्स का क्रम।
...
इस प्रकार, नकल के एक अरब मौके में एक होने के लिए, 103 ट्रिलियन संस्करण 4 UUIDs उत्पन्न होने चाहिए।
UUID.randomUUID()
, न कि किसी सही परिपूर्ण यादृच्छिक संख्या जनरेटर के लिए सैद्धांतिक अवसरों के बारे में।
क्या किसी को साझा करने का कोई अनुभव है?
2^122
टाइप -4 यूयूआईडी के लिए संभावित मूल्य हैं । (युक्ति कहती है कि आप टाइप के लिए 2 बिट्स खो देते हैं, और संस्करण संख्या के लिए आगे 4 बिट्स।)
यह मानते हुए कि आप 1 मिलियन यादृच्छिक यूयूआईडी को एक सेकंड में उत्पन्न करते हैं, आपके जीवनकाल में एक डुप्लिकेट होने की संभावना गायब हो जाएगी। और डुप्लिकेट का पता लगाने के लिए, आपको पहले से उत्पन्न 1 यूआईडी के सभी के खिलाफ प्रति सेकंड 1 मिलियन नए यूयूआईडी की तुलना करने की समस्या को हल करना होगा !
संभावना है कि किसी ने भी अनुभव किया है (यानी वास्तव में देखा गया ) वास्तविक जीवन में एक डुप्लिकेट गायब होने की तुलना में बहुत छोटा है ... टकराव की तलाश की व्यावहारिक कठिनाई के कारण।
अब निश्चित रूप से, आप आमतौर पर एक छद्म यादृच्छिक संख्या जनरेटर का उपयोग कर रहे होंगे, वास्तव में यादृच्छिक संख्याओं का स्रोत नहीं। लेकिन मुझे लगता है कि हम आश्वस्त हो सकते हैं कि यदि आप अपनी क्रिप्टोग्राफ़िक ताकत यादृच्छिक संख्याओं के लिए एक विश्वसनीय प्रदाता का उपयोग कर रहे हैं, तो यह क्रिप्टोग्राफ़िक शक्ति होगी , और दोहराव की संभावना एक आदर्श (गैर-पक्षपाती) रैंडम जनरेटर के समान होगी ।
हालाँकि, यदि आप "टूटी हुई" क्रिप्टो-यादृच्छिक संख्या जनरेटर के साथ एक जेवीएम का उपयोग करने के लिए थे, तो सभी दांव बंद हैं। (और इसमें कुछ सिस्टमों पर "एन्ट्रापी की कमी" समस्याओं के लिए कुछ वर्कअराउंड शामिल हो सकते हैं। या संभावना है कि किसी ने आपके JRE के साथ छेड़छाड़ की है, या तो आपके सिस्टम या अपस्ट्रीम पर।)
1 - यह मानते हुए कि आपने अनाम टिप्पणीकार द्वारा प्रस्तावित "किसी प्रकार की बाइनरी बीट्री" का उपयोग किया है, प्रत्येक यूयूआईडी O(NlogN)
को N
कम घनत्व और बिट्स के यादृच्छिक वितरण मानने वाले विशिष्ट यूयूआईडी का प्रतिनिधित्व करने के लिए रैम मेमोरी के बिट्स की आवश्यकता है । अब इसे 1,000,000 से गुणा करें और आप कितने सेकंड के लिए प्रयोग चलाने वाले हैं। मुझे नहीं लगता कि उच्च गुणवत्ता वाले आरएनजी की टक्करों के परीक्षण के लिए आवश्यक समय की लंबाई के लिए व्यावहारिक है। (काल्पनिक) चतुर अभ्यावेदन के साथ भी नहीं।
मैं एक विशेषज्ञ नहीं हूं, लेकिन मैं मान सकता हूं कि काफी स्मार्ट लोग वर्षों से जावा के यादृच्छिक संख्या जनरेटर को देखते थे। इसलिए, मैं यह भी मानूंगा कि यादृच्छिक UUID अच्छे हैं। तो आपको वास्तव में सभी संभावित यूयूआईडी के लिए सैद्धांतिक टकराव की संभावना (जो 1: 3 × 10 ^ 38 के बारे में है। क्या किसी को पता है कि यह केवल यादृच्छिक यूयूआईडी के लिए कैसे बदलता है? क्या यह 1/(16*4)
ऊपर है?)
अपने व्यावहारिक अनुभव से, मैंने अब तक कोई टक्कर नहीं देखी है। मैं शायद उस दिन एक आश्चर्यजनक लम्बी दाढ़ी बढ़ाऊंगा जिस दिन मुझे अपना पहला अंक मिलेगा;)
एक पूर्व नियोक्ता में हमारे पास एक अद्वितीय कॉलम था जिसमें एक यादृच्छिक यूआईडी शामिल था। हमें तैनात किए जाने के बाद पहले हफ्ते एक टक्कर मिली। ज़रूर, हालात कम हैं, लेकिन वे शून्य नहीं हैं। यही कारण है कि Log4j 2 में UuidUtil.getTimeBasedUuid सम्मिलित है। यह एक यूयूआईडी उत्पन्न करेगा जो 8,925 वर्षों के लिए अद्वितीय है जब तक कि आप एक एकल सर्वर पर 10,000 से अधिक यूयूआईडी / मिलीसेकंड उत्पन्न नहीं करते हैं।
यूयूआईडी के लिए मूल पीढ़ी की योजना यूयूआईडी उत्पन्न करने वाले कंप्यूटर के मैक पते के साथ यूयूआईडी संस्करण को समाप्त करना था, और पश्चिम में ग्रेगोरियन कैलेंडर को अपनाने के बाद से 100-नैनोसेकंड अंतराल की संख्या के साथ। अंतरिक्ष में एक बिंदु (कंप्यूटर) और समय (अंतराल की संख्या) का प्रतिनिधित्व करके, मूल्यों में टकराव की संभावना प्रभावी रूप से बीआईएल है।
कई उत्तर चर्चा करते हैं कि टक्कर के 50% मौके तक पहुंचने के लिए कितने यूयूआईडी उत्पन्न करने होंगे। लेकिन एक 50%, 25%, या यहां तक कि टकराव की 1% संभावना एक आवेदन के लिए बेकार है जहां टकराव (लगभग) असंभव होना चाहिए।
क्या प्रोग्रामर नियमित रूप से "असंभव" अन्य घटनाओं को खारिज कर सकते हैं जो हो सकती हैं और होती हैं?
जब हम किसी डिस्क या मेमोरी में डेटा लिखते हैं और उसे फिर से पढ़ते हैं, तो हम यह मान लेते हैं कि डेटा सही है। हम किसी भी भ्रष्टाचार का पता लगाने के लिए डिवाइस की त्रुटि सुधार पर भरोसा करते हैं। लेकिन अनिर्धारित त्रुटियों का मौका वास्तव में 2 -50 के आसपास है ।
यह यादृच्छिक UUIDs के समान मानक लागू करने के लिए समझ में नहीं आएगा? यदि आप करते हैं, तो आप पाएंगे कि लगभग 100 बिलियन के यादृच्छिक यूयूआईडी ( 2-2.5 ) के संग्रह में "असंभव" टक्कर संभव है ।
यह एक खगोलीय संख्या है, लेकिन एक राष्ट्रीय स्वास्थ्य प्रणाली में आइटम के आकार की बिलिंग, या उपकरणों की एक बड़ी सरणी पर उच्च आवृत्ति सेंसर डेटा लॉगिंग जैसे अनुप्रयोग निश्चित रूप से इन सीमाओं से टकरा सकते हैं। यदि आप गैलेक्सी के लिए अगले सहयात्री गाइड लिख रहे हैं , तो प्रत्येक लेख के लिए UUIDs असाइन करने का प्रयास न करें!
चूँकि अधिकांश उत्तर थ्योरी पर केंद्रित थे, इसलिए मुझे लगता है कि मैंने जो व्यवहारिक परीक्षा दी, उससे मैं चर्चा में कुछ जोड़ सकता हूँ। मेरे डेटाबेस में जावा 8 यूयूआईडी.randomUUID () का उपयोग करके लगभग 4.5 मिलियन UUIDs उत्पन्न हुए हैं। निम्नलिखित कुछ बस मुझे पता चला है:
c0f55f62 -b990-47bc-8caa-f42313669948
c0f55f62 -e81e-4253-8299-00b4322829d5
c0f55f62 -4979-4e87-8cd9-1c556894e2bb
b9ea2498-fb32-40ef-91ef-0ba 00060fe64
be87a209-2114-45b3-9d5a-86d 00060fe64
4a8a74a6-e972-4069-b480-b dea1177b21f
12fb4958-bee2-4c89-8cf8-e dea1177b21f
यदि यह वास्तव में यादृच्छिक था, तो इस तरह के यूयूआईडी के होने की संभावना काफी कम होगी (देखें संपादित करें), क्योंकि हम केवल 4.5 मिलियन प्रविष्टियों पर विचार कर रहे हैं। इसलिए, हालांकि यह फ़ंक्शन अच्छा है, टकराव न होने के संदर्भ में, मेरे लिए यह उतना अच्छा नहीं लगता जितना कि सिद्धांत में होगा।
संपादित करें :
बहुत से लोग इस उत्तर को नहीं समझते हैं इसलिए मैं अपनी बात स्पष्ट करूंगा: मुझे पता है कि समानताएं "छोटी" हैं और एक पूर्ण टक्कर से दूर हैं। हालांकि, मैं सिर्फ जावा के UUID.randomUUID () की तुलना एक सच्चे यादृच्छिक संख्या जनरेटर से करना चाहता था, जो कि वास्तविक प्रश्न है।
एक सच्चे यादृच्छिक संख्या जनरेटर में, अंतिम मामले की संभावना लगभग = 0.007% होगी। इसलिए, मुझे लगता है कि मेरा निष्कर्ष खड़ा है।
इस विकी लेख en.wikipedia.org/wiki/Birthday_problem में सूत्र की व्याख्या की गई है
मैं पिछले साल लॉटरी में खेलता हूं, और मैं कभी नहीं जीता .... लेकिन ऐसा लगता है कि लॉटरी में विजेता हैं ...
doc: http://tools.ietf.org/html/rfc4122
टाइप 1: लागू नहीं। यदि एक ही पल में यूयूड उत्पन्न होता है तो टकराव संभव है। इस समस्या को दरकिनार करने के लिए इम्प्लांट को कृत्रिम रूप से सिंक्रोनाइज़ किया जा सकता है।
टाइप 2: कभी भी क्रियान्वयन न देखें।
टाइप 3: md5 हैश: टक्कर संभव (128 बिट्स -2 तकनीकी बाइट्स)
टाइप 4: यादृच्छिक: टक्कर संभव (लॉटरी के रूप में)। ध्यान दें कि jdk6 का अर्थ यह नहीं है कि "असली" सुरक्षित यादृच्छिक का उपयोग करें क्योंकि PRNG एल्गोरिथ्म डेवलपर द्वारा नहीं चुना गया है और आप सिस्टम को "खराब" PRNG एल्गो का उपयोग करने के लिए मजबूर कर सकते हैं। तो आपका UUID प्रेडिक्टेबल है।
टाइप 5: sha1 हैश: लागू नहीं: टक्कर संभव (160 बिट -2 तकनीकी बाइट्स)