जावा का UUID.randomUUID कितना अच्छा है?


311

मुझे पता है कि यादृच्छिक UUIDs के सिद्धांत में टकराव के लिए बहुत, बहुत कम संभावना है, लेकिन मैं सोच रहा हूं, व्यवहार में, randomUUID()टक्कर नहीं होने के मामले में जावा कितना अच्छा है? क्या किसी को साझा करने का कोई अनुभव है?


10
मेरे अनुभव में, मैंने कभी टक्कर नहीं देखी ;-)
थिलो

4
एल्गोरिदम RFC1422 में निर्दिष्ट हैं: ietf.org/rfc/rfc4122.txt
skaffman

8
@skaffman: RFC यादृच्छिक अंकों को उत्पन्न करने के लिए उपयोग किए जाने वाले एल्गोरिदम के बारे में बिल्कुल कुछ नहीं कहता है।
माइकल बोर्गवर्ड

4
चूंकि यह अधिक खुला समाप्त प्रश्न है, इसलिए मुझे लगता है कि मैं किसी भी उत्तर को सही उत्तर के रूप में चिह्नित नहीं करूंगा; इसके बजाय, मैं प्रत्येक उत्तर के लिए एक वोट दूंगा जो मुझे लगता है कि अच्छा है :)
एल्विन

5
विकिपीडिया से: ... दूसरे शब्दों में, अगले 100 वर्षों के लिए हर सेकंड 1 बिलियन यूयूआईडी बनाने के बाद, केवल एक डुप्लिकेट बनाने की संभावना लगभग 50% होगी।
MaVRoSCy

जवाबों:


168

यूयूआईडी का उपयोग करता है java.security.SecureRandom, जिसे "क्रिप्टोग्राफिक रूप से मजबूत" माना जाता है। हालांकि वास्तविक कार्यान्वयन निर्दिष्ट नहीं है और जेवीएम के बीच भिन्न हो सकता है (जिसका अर्थ है कि किए गए किसी भी ठोस बयान केवल एक विशिष्ट जेवीएम के लिए मान्य हैं), यह अनिवार्य है कि आउटपुट को एक सांख्यिकीय यादृच्छिक संख्या जनरेटर परीक्षण पास करना होगा।

एक कार्यान्वयन के लिए यह हमेशा संभव है कि इसमें सूक्ष्म कीड़े शामिल हों जो यह सब बर्बाद करते हैं (ओपनएसएसएच कुंजी पीढ़ी बग देखें) लेकिन मुझे नहीं लगता कि जावा यूयूआईडीएस की यादृच्छिकता के बारे में चिंता करने का कोई ठोस कारण है।


34
"सूक्ष्म बग को लागू करने के लिए यह हमेशा संभव है ..." - या (टिन-फ़ॉइल टोपी का दान) ... सूक्ष्म दोषों को जानबूझकर। <:-)
स्टीफन सी

25
टकराव के सवाल के लिए क्रिप्टोग्राफिक ताकत पूरी तरह से अप्रासंगिक है।
osa

14
@ डोसा: टक्कर उत्पन्न नहीं करना (पूर्ण यादृच्छिकता से अपेक्षित होने से अधिक) एक आरएनजी के लिए सबसे कम गुणवत्ता की आवश्यकता है, जबकि क्रिप्टोग्राफिक ताकत सबसे अधिक है। दूसरे शब्दों में, क्रिप्टोग्राफिक रूप से मजबूत आरएनजी सबसे निश्चित रूप से उम्मीद से अधिक टकराव पैदा नहीं करेगा ।
माइकल बोर्गवर्ड्ट

3
यह नोट करना उपयोगी हो सकता है, हालांकि, अगर आप उदाहरण के लिए ब्लॉग्स .vmware.com / cto /… के अंदर UUIDs को मंथन करने वाला एक JVM चलाते हैं , तो आपको संभवतः कई, कई टक्कर मिलेंगी। सभी सॉफ्टवेयर RNG PRNGs हैं, और वे अंततः केवल एंट्रोपी के अपने स्रोत के रूप में अच्छे हैं; दो PRNGs जो बीज बोने के लिए समान रूप से पहचाने जाते हैं, और यह आश्चर्यजनक रूप से अक्सर सुसंगत, सटीक-डुप्लिकेट सर्वर सेटअप और स्टार्टअप प्रक्रियाओं के साथ हो सकता है।
user508633

@ user508633: मैं वास्तव में उस विशिष्ट मामले में 100% टक्कर की दर प्राप्त करने की उम्मीद करूंगा, लेकिन यह वास्तव में एक बहुत ही विशिष्ट मामला है जो "सुसंगत, सटीक-डुप्लीकेट सर्वर सेटअप और स्टार्टअप प्रक्रियाओं" से बहुत आगे जाता है। मुझे पूरा यकीन है कि आपको कोई बढ़ी हुई टक्कर की दरें नहीं मिलेंगी यदि आप केवल एक वीएम को क्लोन करते हैं और इसे सामान्य रूप से चलाते हैं। सिक्योर रैंडम का आत्म-बीजारोपण कुछ वास्तविक एन्ट्रापी प्राप्त करने के लिए बहुत कठिन प्रयास करता है, अगर यह किसी भी नहीं मिल सकता है तो निष्पादन को अवरुद्ध करने के बिंदु पर: seancassidy.me/wiggle-the-mouse-to-fix-the-tub.html
माइकल Borgwardt

114

विकिपीडिया का बहुत अच्छा जवाब है http://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions

यादृच्छिक संस्करण 4 यूयूआईडी की संख्या जिसे उत्पन्न करने की आवश्यकता है ताकि कम से कम एक टक्कर की 50% संभावना हो 2.71 क्विंटल, इस प्रकार गणना की गई है:

...

यह संख्या लगभग 85 वर्षों के लिए 1 बिलियन यूयूआईडी प्रति सेकंड उत्पन्न करने के बराबर है, और इस फाइल में कई यूयूआईडी हैं, जिसमें 16 बाइट्स प्रति यूयूआईडी हैं, लगभग 45 एक्साबाइट होंगे, जो वर्तमान में अस्तित्व में सबसे बड़े डेटाबेस से कई गुना बड़ा है, जो चालू हैं सैकड़ों पेटाबाइट्स का क्रम।

...

इस प्रकार, नकल के एक अरब मौके में एक होने के लिए, 103 ट्रिलियन संस्करण 4 UUIDs उत्पन्न होने चाहिए।


56
मैं उस पृष्ठ से भी उद्धृत करता हूं, "यदि एक डुप्लिकेट की संभावना लगभग 50% होगी यदि पृथ्वी पर प्रत्येक व्यक्ति 600 मिलियन यूयूएस का मालिक है।"
जेफ एक्सल्रॉड

24
यह केवल सही यादृच्छिकता के लिए सही है, न कि javas UUIDs जैसे छद्म आयामी संख्याओं के लिए।
मार्कस

9
@ मर्कस: पूरी तरह से गलत। अच्छे छद्म आयामी RNGs के लिए टकराव की संभावना, विशेष रूप से क्रिप्टोग्राफिक रूप से मजबूत वाले, "सत्य" यादृच्छिकता से अलग नहीं है।
माइकल बॉर्गवर्ड

6
@ एरिक - मुझे लगता है कि आप अपने दावे का समर्थन करने के लिए onus है। एफडब्ल्यूआईडब्ल्यू, केवल परिदृश्य मैं सोच सकता हूं कि टाइप 4 यूयूआईडी कहां बार-बार टकराएगा कि संभावना सिद्धांत कहता है: 1) क्रिप्टो यादृच्छिक संख्या का एक बुरा स्रोत है, या 2) एक यूयूआईडी लाइब्रेरी जो समझौता किया गया है।
स्टीफन सी।

13
यह पूछे गए प्रश्न का उत्तर नहीं देता है। सवाल जावा में यादृच्छिकता की गुणवत्ता के बारे में है UUID.randomUUID(), न कि किसी सही परिपूर्ण यादृच्छिक संख्या जनरेटर के लिए सैद्धांतिक अवसरों के बारे में।
क्रेटेंको

69

क्या किसी को साझा करने का कोई अनुभव है?

2^122टाइप -4 यूयूआईडी के लिए संभावित मूल्य हैं । (युक्ति कहती है कि आप टाइप के लिए 2 बिट्स खो देते हैं, और संस्करण संख्या के लिए आगे 4 बिट्स।)

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

संभावना है कि किसी ने भी अनुभव किया है (यानी वास्तव में देखा गया ) वास्तविक जीवन में एक डुप्लिकेट गायब होने की तुलना में बहुत छोटा है ... टकराव की तलाश की व्यावहारिक कठिनाई के कारण।

अब निश्चित रूप से, आप आमतौर पर एक छद्म यादृच्छिक संख्या जनरेटर का उपयोग कर रहे होंगे, वास्तव में यादृच्छिक संख्याओं का स्रोत नहीं। लेकिन मुझे लगता है कि हम आश्वस्त हो सकते हैं कि यदि आप अपनी क्रिप्टोग्राफ़िक ताकत यादृच्छिक संख्याओं के लिए एक विश्वसनीय प्रदाता का उपयोग कर रहे हैं, तो यह क्रिप्टोग्राफ़िक शक्ति होगी , और दोहराव की संभावना एक आदर्श (गैर-पक्षपाती) रैंडम जनरेटर के समान होगी ।

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


1 - यह मानते हुए कि आपने अनाम टिप्पणीकार द्वारा प्रस्तावित "किसी प्रकार की बाइनरी बीट्री" का उपयोग किया है, प्रत्येक यूयूआईडी O(NlogN)को Nकम घनत्व और बिट्स के यादृच्छिक वितरण मानने वाले विशिष्ट यूयूआईडी का प्रतिनिधित्व करने के लिए रैम मेमोरी के बिट्स की आवश्यकता है । अब इसे 1,000,000 से गुणा करें और आप कितने सेकंड के लिए प्रयोग चलाने वाले हैं। मुझे नहीं लगता कि उच्च गुणवत्ता वाले आरएनजी की टक्करों के परीक्षण के लिए आवश्यक समय की लंबाई के लिए व्यावहारिक है। (काल्पनिक) चतुर अभ्यावेदन के साथ भी नहीं।


4
"(और डुप्लिकेट का पता लगाने के लिए, आपको पहले से उत्पन्न सभी UUIDs के खिलाफ प्रति सेकंड 1 मिलियन नए UUIDs की तुलना करने की समस्या को हल करना होगा!)" - यह हिस्सा अपेक्षाकृत सरल है यह मानते हुए कि आपने कुछ में अपने uids को संग्रहीत किया है। बाइनरी ट्री संरचना की तरह, यह नए यूआईडी के अनुसार सिर्फ एक पेड़ होगा। आप वास्तव में सभी पहले से उत्पन्न uuids के खिलाफ इसे व्यक्तिगत रूप से तुलना करने की आवश्यकता नहीं होगी।
user467257

20

मैं एक विशेषज्ञ नहीं हूं, लेकिन मैं मान सकता हूं कि काफी स्मार्ट लोग वर्षों से जावा के यादृच्छिक संख्या जनरेटर को देखते थे। इसलिए, मैं यह भी मानूंगा कि यादृच्छिक UUID अच्छे हैं। तो आपको वास्तव में सभी संभावित यूयूआईडी के लिए सैद्धांतिक टकराव की संभावना (जो 1: 3 × 10 ^ 38 के बारे में है। क्या किसी को पता है कि यह केवल यादृच्छिक यूयूआईडी के लिए कैसे बदलता है? क्या यह 1/(16*4)ऊपर है?)

अपने व्यावहारिक अनुभव से, मैंने अब तक कोई टक्कर नहीं देखी है। मैं शायद उस दिन एक आश्चर्यजनक लम्बी दाढ़ी बढ़ाऊंगा जिस दिन मुझे अपना पहला अंक मिलेगा;)


10
विकिपीडिया से: ... दूसरे शब्दों में, अगले 100 वर्षों के लिए हर सेकंड 1 बिलियन यूयूआईडी बनाने के बाद, केवल एक डुप्लिकेट बनाने की संभावना लगभग 50% होगी।
MaVRoSCy

1
वास्तव में विकिपीडिया कहता है कि यह अगले 85 वर्षों के लिए है ... मैं कहता हूं कि इस पर भरोसा मत करो, किसी ने आपके समान ही UUID उत्पन्न किया है
smac89

12

एक पूर्व नियोक्ता में हमारे पास एक अद्वितीय कॉलम था जिसमें एक यादृच्छिक यूआईडी शामिल था। हमें तैनात किए जाने के बाद पहले हफ्ते एक टक्कर मिली। ज़रूर, हालात कम हैं, लेकिन वे शून्य नहीं हैं। यही कारण है कि Log4j 2 में UuidUtil.getTimeBasedUuid सम्‍मिलित है। यह एक यूयूआईडी उत्पन्न करेगा जो 8,925 वर्षों के लिए अद्वितीय है जब तक कि आप एक एकल सर्वर पर 10,000 से अधिक यूयूआईडी / मिलीसेकंड उत्पन्न नहीं करते हैं।


2
हाँ। लेकिन सवाल यादृच्छिक (यानी टाइप -4) यूयूआईडी के बारे में पूछ रहा है।
स्टीफन C

1
यह टक्कर मिलने की संभावना के बारे में पूछ रहा है। निहितार्थ यह है कि वह उनसे बचना सुनिश्चित करना चाहता है।
rgoers

1
(टक्कर PRNGs के बोने के लिए यादृच्छिकता के टूटे स्रोत के कारण सबसे अधिक संभावना थी। मैंने सोचा कि यह संभव है कि यह शुद्ध मौका के कारण था।)
स्टीफन सी

9

यूयूआईडी के लिए मूल पीढ़ी की योजना यूयूआईडी उत्पन्न करने वाले कंप्यूटर के मैक पते के साथ यूयूआईडी संस्करण को समाप्‍त करना था, और पश्चिम में ग्रेगोरियन कैलेंडर को अपनाने के बाद से 100-नैनोसेकंड अंतराल की संख्या के साथ। अंतरिक्ष में एक बिंदु (कंप्यूटर) और समय (अंतराल की संख्या) का प्रतिनिधित्व करके, मूल्यों में टकराव की संभावना प्रभावी रूप से बीआईएल है।


1
यह स्पष्टीकरण मुझे आशावादी बनाता है कि अभ्यास में टकराव न देखें। क्या आप इस कथन के लिए किसी संदर्भ का उल्लेख कर सकते हैं (कुछ स्रोत कोड और भी बेहतर होगा)?
ड्रेगन मार्जनोविच

इसे ietf.org/rfc/rfc4122.txt के चश्मे से मिला । फिर भी कार्यान्वयन देखना बहुत अच्छा होगा।
ड्रैगन मार्जनोविच

1
हालांकि यह योजना जावा लागू नहीं करती है। जावा लागू 4 यूयूआईडी टाइप करता है, जो शुद्ध यादृच्छिक है और इसमें मैक एड्रेस या समय शामिल नहीं है। संयोग से, चूंकि अब कई भौतिक और आभासी डिवाइस हैं जहां आप अपना मैक पता चुन सकते हैं, मूल एल्गोरिथ्म विशिष्टता की गारंटी नहीं देता है।
सोरेन बोइसन

8

कई उत्तर चर्चा करते हैं कि टक्कर के 50% मौके तक पहुंचने के लिए कितने यूयूआईडी उत्पन्न करने होंगे। लेकिन एक 50%, 25%, या यहां तक ​​कि टकराव की 1% संभावना एक आवेदन के लिए बेकार है जहां टकराव (लगभग) असंभव होना चाहिए।

क्या प्रोग्रामर नियमित रूप से "असंभव" अन्य घटनाओं को खारिज कर सकते हैं जो हो सकती हैं और होती हैं?

जब हम किसी डिस्क या मेमोरी में डेटा लिखते हैं और उसे फिर से पढ़ते हैं, तो हम यह मान लेते हैं कि डेटा सही है। हम किसी भी भ्रष्टाचार का पता लगाने के लिए डिवाइस की त्रुटि सुधार पर भरोसा करते हैं। लेकिन अनिर्धारित त्रुटियों का मौका वास्तव में 2 -50 के आसपास है ।

यह यादृच्छिक UUIDs के समान मानक लागू करने के लिए समझ में नहीं आएगा? यदि आप करते हैं, तो आप पाएंगे कि लगभग 100 बिलियन के यादृच्छिक यूयूआईडी ( 2-2.5 ) के संग्रह में "असंभव" टक्कर संभव है ।

यह एक खगोलीय संख्या है, लेकिन एक राष्ट्रीय स्वास्थ्य प्रणाली में आइटम के आकार की बिलिंग, या उपकरणों की एक बड़ी सरणी पर उच्च आवृत्ति सेंसर डेटा लॉगिंग जैसे अनुप्रयोग निश्चित रूप से इन सीमाओं से टकरा सकते हैं। यदि आप गैलेक्सी के लिए अगले सहयात्री गाइड लिख रहे हैं , तो प्रत्येक लेख के लिए UUIDs असाइन करने का प्रयास न करें!


तुलना के बिंदु के रूप में, एक पावरबॉल जैकपॉट जीतने का मौका 300 मिलियन में 1 है, लेकिन 10 से 20 मिलियन टिकटों की बिक्री विशिष्ट है। मुद्दा यह है कि कई लोग "असंभव" को सैकड़ों लाखों में एक मौका से कम के रूप में परिभाषित करते हैं ।
एरिकसन

4

चूँकि अधिकांश उत्तर थ्योरी पर केंद्रित थे, इसलिए मुझे लगता है कि मैंने जो व्यवहारिक परीक्षा दी, उससे मैं चर्चा में कुछ जोड़ सकता हूँ। मेरे डेटाबेस में जावा 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 में सूत्र की व्याख्या की गई है


6
यह सच नहीं है। इस तरह की समानताएं 4.5M uuids पर एक सच्चे यादृच्छिक संख्या जनरेटर के साथ भी उत्पन्न होंगी। UUIDs के बीच समानताएं आपके द्वारा दी गई छोटी और दूर हैं, ओह एक पूर्ण टक्कर से अब तक।
user3711864

मैं आपसे पूरी तरह सहमत हूं कि समानताएं "छोटी" हैं और एक पूर्ण टक्कर से दूर हैं। हालांकि, मैं सिर्फ जावा के UUID.randomUUID () की तुलना एक सच्चे यादृच्छिक संख्या जनरेटर के साथ करना चाहता था (यह सवाल है)। कुछ गणनाओं के साथ, हम देख सकते हैं कि, एक सच्चे यादृच्छिक संख्या जनरेटर में, पिछले मामले की संभावना लगभग 1-ई ^ (- 4500000 ^ 2 / (2 * 36 ^ 11)) = 0.007% = 1 होगी 13k। मुझे बहुत भाग्यशाली होना पड़ेगा :)
एंड्रे

1
4.5 मिलियन आइटम और 13 के मौके में 1 के साथ, 346 बार होने की उम्मीद की तरह आंशिक टक्कर नहीं होगी ?
बेन ली

नहीं @BenLee, मैंने उस घटना की संभावना की गणना करते हुए विचार किया कि हमारे पास 4.5 मिलियन आइटम हैं। यह प्रत्येक आइटम के लिए होने के लिए 13k मौका में 1 नहीं है। मेरे द्वारा उपयोग किया गया सूत्र इस विकी लेख en.wikipedia.org/wiki/Birthday_problem
André Pinheiro

2
आपकी अपेक्षा क्या थी? समान नहीं है, यह नहीं है?
कोरे तुगे

3

मैं पिछले साल लॉटरी में खेलता हूं, और मैं कभी नहीं जीता .... लेकिन ऐसा लगता है कि लॉटरी में विजेता हैं ...

doc: http://tools.ietf.org/html/rfc4122

टाइप 1: लागू नहीं। यदि एक ही पल में यूयूड उत्पन्न होता है तो टकराव संभव है। इस समस्या को दरकिनार करने के लिए इम्प्लांट को कृत्रिम रूप से सिंक्रोनाइज़ किया जा सकता है।

टाइप 2: कभी भी क्रियान्वयन न देखें।

टाइप 3: md5 हैश: टक्कर संभव (128 बिट्स -2 तकनीकी बाइट्स)

टाइप 4: यादृच्छिक: टक्कर संभव (लॉटरी के रूप में)। ध्यान दें कि jdk6 का अर्थ यह नहीं है कि "असली" सुरक्षित यादृच्छिक का उपयोग करें क्योंकि PRNG एल्गोरिथ्म डेवलपर द्वारा नहीं चुना गया है और आप सिस्टम को "खराब" PRNG एल्गो का उपयोग करने के लिए मजबूर कर सकते हैं। तो आपका UUID प्रेडिक्टेबल है।

टाइप 5: sha1 हैश: लागू नहीं: टक्कर संभव (160 बिट -2 तकनीकी बाइट्स)


4
लॉटरी जीतने की संभावना 10 या 100 मिलियन (10 ^ 7 या 10 ^ 8) में से एक है या ऐसा ही कुछ। 128 बिट यादृच्छिक संख्या के साथ टकराव की संभावना 3.4 * 10 ^ 28 है। मुझे कभी भी लॉटरी टिकट दे दो!
स्टीफन सी

0

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

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