जावा में एक UUID के सबसे महत्वपूर्ण बिट्स का उपयोग करके टकराव की संभावना


235

अगर मैं उपयोग कर रहा हूं तो Long uuid = UUID.randomUUID().getMostSignificantBits()टक्कर मिलने की कितनी संभावना है। यह कम से कम महत्वपूर्ण बिट्स को काट देता है, इसलिए संभावना है कि आप टकराव में भागते हैं, है ना?

जवाबों:


213

प्रलेखन के अनुसार , स्थैतिक विधि UUID.randomUUID()एक प्रकार 4 यूयूआईडी उत्पन्न करती है।

इसका मतलब है कि छह बिट्स का उपयोग कुछ प्रकार की जानकारी के लिए किया जाता है और शेष 122 बिट्स को यादृच्छिक रूप से असाइन किया जाता है।

छह गैर-यादृच्छिक बिट्स को यूयूआईडी के सबसे महत्वपूर्ण आधे में चार और सबसे कम महत्वपूर्ण आधे में दो के साथ वितरित किया जाता है। इसलिए आपके UUID के सबसे महत्वपूर्ण आधे हिस्से में 60 बिट्स की यादृच्छिकता है, जिसका अर्थ है कि आपको टक्कर पाने के लिए औसतन 2 ^ 30 UUID उत्पन्न करने की आवश्यकता है (पूर्ण UUID के लिए 2 ^ 61 की तुलना में)।

तो मैं कहूंगा कि आप सुरक्षित हैं। ध्यान दें, हालांकि यह अन्य प्रकार के यूयूआईडी के लिए बिल्कुल सही नहीं है, जैसा कि कार्ल सेलेबर्ग उल्लेख करते हैं।

संयोग से, आप यूयूआईडी के कम से कम महत्वपूर्ण आधे हिस्से का उपयोग करके (या सिर्फ सिक्योरगेम का उपयोग करके एक यादृच्छिक लंबे समय का उत्पादन करके) थोड़ा बेहतर होगा।


3
मुझे यकीन नहीं है कि यह पूरी तरह से सही है - कार्यान्वयन को देखते हुए, यह स्पष्ट है कि संस्करण / संस्करण की जानकारी सबसे महत्वपूर्ण बिट्स में संग्रहीत नहीं है, बल्कि बीच में कहीं है।
टॉम

2
@RasmusFaber टॉम द्वारा की गई टिप्पणी सही है: यहां उत्तर छह सबसे महत्वपूर्ण बिट्स प्रकार की जानकारी होने के बारे में गलत है । गैर-यादृच्छिक डेटा के वास्तव में छह बिट्स हैं लेकिन चार बिट्स संस्करण 4 की पहचान करते हैं और दो अन्य बिट्स आरक्षित हैं। चार और दो बिट्स 128-बिट मान के मध्य के पास विभिन्न पदों पर स्थित हैं। विकिपीडिया लेख देखें ।
बेसिल बॉर्कल

56

रेमंड चेन इस पर एक बहुत अच्छा ब्लॉग पोस्ट है:

GUIDs विश्व स्तर पर अद्वितीय हैं, लेकिन GUIDs के सबस्ट्रिंग नहीं हैं


1
लिंक किसी भी अधिक मृत नहीं है।
दाविद वेसेज़लोवस्की

3
लिंक एक बार फिर से मर चुका है। यहां वेब संग्रह संस्करण का लिंक दिया गया है ।
कुबा स्पैटनी


10

आप केवल एक यादृच्छिक लंबे मूल्य पैदा करने से बेहतर हैं, फिर सभी बिट्स यादृच्छिक हैं। जावा 6 में, नया रैंडम () System.nanoTime () और एक बीज के रूप में एक काउंटर का उपयोग करता है।

विशिष्टता के विभिन्न स्तर हैं।

यदि आपको कई मशीनों में विशिष्टता की आवश्यकता है, तो आपके पास अद्वितीय आईडी, या यहां तक ​​कि अद्वितीय आईडी के बैचों के आवंटन के लिए एक केंद्रीय डेटाबेस तालिका हो सकती है।

यदि आपको बस एक ऐप में विशिष्टता रखने की आवश्यकता है, तो आपके पास केवल एक काउंटर (या एक काउंटर हो सकता है जो currentTimeMillis () * 1000 या नैनो टाइम) से शुरू होता है (आपकी आवश्यकताओं के आधार पर)


7

YYYYDDDDउपसर्ग के रूप में समय (वर्ष + वर्ष का वर्ष) का उपयोग करें । यह टेबल और इंडेक्स में डेटाबेस के विखंडन को कम करता है। यह विधि लौटती है byte[40]। मैंने इसे एक हाइब्रिड वातावरण में उपयोग किया है जहां varbinary(85)एलडीएपी उपयोगकर्ताओं के लिए सक्रिय निर्देशिका एसआईडी ( ) कुंजी है और गैर-एलडीएपी उपयोगकर्ताओं के लिए एक एप्लिकेशन ऑटो-जनरेट आईडी का उपयोग किया जाता है। लेन-देन तालिका (बैंकिंग उद्योग) में प्रति दिन बड़ी संख्या में लेनदेन Intकुंजी के लिए मानक प्रकारों का उपयोग नहीं कर सकते हैं

private static final DecimalFormat timeFormat4 = new DecimalFormat("0000;0000");

public static byte[] getSidWithCalendar() {
    Calendar cal = Calendar.getInstance();
    String val = String.valueOf(cal.get(Calendar.YEAR));
    val += timeFormat4.format(cal.get(Calendar.DAY_OF_YEAR));
    val += UUID.randomUUID().toString().replaceAll("-", "");
    return val.getBytes();
}

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