UUID जनरेटर

v4 या समय के क्रम वाले v7 UUID बनाएँ, और अपने मौजूदा UUID की जाँच करें।

5

यादृच्छिक UUID

    किसी UUID की जाँच करें

    कोई एक चिपकाएँ और देखें कि वह किस संस्करण का है और उसमें कुछ समाया है या नहीं।

    वर्शन, और इनमें से दो ही मायने रखते हैं

    आठ वर्शन हैं, और नए काम के लिए चुनाव असल में दो में से ही है। बाक़ी को पहचान लेना काम का है, ताकि किसी पुराने सिस्टम में मिलने पर पता चल जाए।

    वर्शनकिससे बनाकब इस्तेमाल करें
    v4122 यादृच्छिक बिटजब अनुमान लगाना नामुमकिन चाहिए। टोकन और पहचानकर्ताओं के लिए डिफ़ॉल्ट।
    v7टाइमस्टैम्प + यादृच्छिकताजब डेटाबेस की-चाहिए। बनने के समय के क्रम में लगता है।
    v1टाइमस्टैम्प + MAC पतापुरानी विरासत। मशीन और समय दोनों उजागर करता है।
    v3 / v5नेमस्पेस और नाम का हैशजब एक ही इनपुट से हमेशा एक ही ID चाहिए।
    v6क्रम बदला हुआ v1v1 का डेटा माइग्रेट कर रहे हों और चाहते हों कि वह क्रम में लगे।
    v8जो आप तय करेंक़रीब-क़रीब कभी नहीं।

    इंडेक्स की समस्या, जो v7 के होने की असली वजह है

    यही व्यावहारिक तर्क है, और इसे मान लेने के बजाय समझ लेना बेहतर है।

    डेटाबेस की प्राइमरी की B-ट्री में, क्रम से रखी जाती है। लगातार बढ़ते पूर्णांक डालिए तो हर नई पंक्ति दाएँ किनारे पर जा बैठती है: एक ही पेज मेमोरी में गरम बना रहता है, पेड़ सलीक़े से बढ़ता है, और लिखना सस्ता रहता है।

    v4 UUID डालिए तो हर पंक्ति कहीं भी, किसी भी जगह जा गिरती है। पूरे पेड़ में जगह-जगह पेज छुए जाते हैं, हर एक को लिखने से पहले पढ़ना पड़ता है, और भरते-भरते पेज बँट जाते हैं। किसी भी ठीक-ठाक आकार के टेबल पर लिखने की क्षमता साफ़ गिरती है और इंडेक्स बिखरता है — यह असर अच्छी तरह दर्ज है, और UUID की-को बदनामी इसी से मिली।

    v7 इसे टाइमस्टैम्प को सबसे आगे रखकर ठीक करता है। ऊपर v7 चुनकर मुट्ठी भर बनाइए और साझा प्रीफ़िक्स देखिए: पास-पास बने मान अगल-बगल होते हैं, इसलिए इंसर्ट पूर्णांक की तरह इंडेक्स के आख़िर में जुड़ते जाते हैं और वैश्विक विशिष्टता भी बनी रहती है। जिस गुण ने UUID को आकर्षक बनाया था — कहीं भी, बिना किसी तालमेल के ID बना लेना — वह आपके पास रहता है, और हर लिखाई पर उसकी क़ीमत नहीं चुकानी पड़ती।

    ठीक-ठीक कहें तो: क्रम की गारंटी अलग-अलग मिलीसेकंडों के बीच है, एक ही मिलीसेकंड के भीतर नहीं। एक ही मिलीसेकंड में बने दो v7 UUID अपने यादृच्छिक पुछल्लों के हिसाब से क्रम में लगते हैं, जिसकी RFC 9562 इजाज़त देता है और चाहें तो कार्यान्वयन इसे काउंटर से कसकर बाँध भी सकते हैं। इंडेक्स-लोकैलिटी वाले तर्क पर इससे कोई फ़र्क़ नहीं पड़ता, क्योंकि वह सिर्फ़ शुरू के टाइमस्टैम्प पर टिका है।

    दोनों पर बची रहने वाली क़ीमत: 4 या 8 के बदले 16 बाइट, और वह भी हर उस इंडेक्स में दोहराई हुई जो उस की-का ज़िक्र करता है। कई फ़ॉरेन की वाले बड़े टेबल पर वह सचमुच की डिस्क है।

    v7 क्या ज़ाहिर कर देता है

    टाइमस्टैम्प उस पहचानकर्ता को रखने वाला हर कोई पढ़ सकता है। ऊपर वाले इंस्पेक्टर में कोई v7 UUID चिपकाइए और वह बता देगा कि वह किस मिलीसेकंड बना था।

    आम तौर पर बेज़रर। कभी-कभी नहीं: किसी सार्वजनिक URL में मौजूद v7 पहचानकर्ता बता देता है कि रिकॉर्ड कब बना, और इतना ही साइन-अप की रफ़्तार, ऑर्डर की मात्रा, या यह कि किसी दस्तावेज़ पर पिछली तारीख़ डाली गई है — इन सबका अनुमान लगाने के लिए काफ़ी हो सकता है। अगर यह मायने रखता है, तो सीधा बँटवारा यह है: जो कुछ उपयोगकर्ता को दिखे उसके लिए v4, और भीतरी की-के लिए v7।

    जहाँ यादृच्छिकता का असली होना ज़रूरी है

    टकराव का जो गणित सब उद्धृत करते हैं — एक टकराव की आधी संभावना तक पहुँचने से पहले 2.7 क्विंटिलियन — वह 122 सचमुच यादृच्छिक बिट मानकर चलता है। वह इस फ़ॉर्मैट के बारे में कथन है, आपके कार्यान्वयन के बारे में नहीं।

    Math.random() पर बना UUID न वह एंट्रॉपी रखता है और न वह अप्रत्याशितता जिसका वह आँकड़ा इशारा करता है, और असल दुनिया में हुए टकराव लगभग हमेशा इसी वजह से हुए हैं, बदक़िस्मती से नहीं। एक ही सेकंड में, एक ही सीड से शुरू हुई दो प्रक्रियाएँ वही क्रम बनाती हैं।

    यह पेज जहाँ crypto.randomUUID() मौजूद है वहाँ उसका, और बाक़ी जगह crypto.getRandomValues का इस्तेमाल करता है। आपका अपना कोड क्या इस्तेमाल करता है, यह जाँच लेना काम का है — ख़ासकर तब जब UUID टोकन की जगह ले रहे हों, क्योंकि अनुमान लगाने लायक़ पासवर्ड-रीसेट पहचानकर्ता का मतलब है पूरा खाता ही चला जाना।

    इन्हें किफ़ायत से सहेजना

    36 अक्षरों वाला टेक्स्ट रूप सुविधाजनक भी है और फ़िज़ूलख़र्च भी। विकल्प — और सब वही 128 बिट:

    • नेटिव UUID टाइप — Postgres में एक है, और वह 16 बाइट सहेजता है। उसी का इस्तेमाल कीजिए।
    • `BINARY(16)` — MySQL का समकक्ष, CHAR(36) के मुक़ाबले क़रीब आधा भंडारण।
    • Base64 — 22 अक्षर, जब उसका टेक्स्ट होना ज़रूरी हो और लंबाई मायने रखती हो।
    • Base32 — 26 अक्षर, छोटे-बड़े अक्षरों का फ़र्क़ नहीं; अगर कभी किसी इंसान को इसे बोलकर पढ़ना पड़े तो यही चाहिए।

    संबंधित

    जो राज़ मशीन को सहेजने नहीं, इंसान को टाइप करने पड़ते हैं, उनके लिए पासवर्ड जनरेटर यही यादृच्छिक स्रोत इस्तेमाल करता है। और v7 UUID में से टाइमस्टैम्प को किसी दूसरे रूप में पढ़ने के लिए, आगे का काम टाइमस्टैम्प कन्वर्टर सँभाल लेता है।

    UUID से जुड़े सवाल

    क्या दो UUID टकरा सकते हैं?

    सैद्धांतिक रूप से हाँ; व्यवहार में नहीं, बशर्ते यादृच्छिकता असली हो। v4 UUID में 122 यादृच्छिक बिट होते हैं, और एक भी टकराव की 50% संभावना तक पहुँचने के लिए आपको लगभग 2.7 क्विंटिलियन UUID बनाने पड़ेंगे — यानी 85 साल तक हर सेकंड एक अरब। असली गड़बड़ी कभी गणित में नहीं होती: वह कमज़ोर यादृच्छिक स्रोत में होती है। Math.random() या ख़राब सीड वाले PRNG पर बना UUID टकरा सकता है और टकराता भी है — इसीलिए यह पेज ब्राउज़र के क्रिप्टोग्राफ़िक स्रोत का इस्तेमाल करता है।

    क्या मुझे डेटाबेस की प्राइमरी की के तौर पर UUID इस्तेमाल करना चाहिए?

    यह वर्शन पर निर्भर है, और फ़र्क़ बड़ा है। v4 UUID यादृच्छिक होता है, इसलिए लगातार होने वाले इंसर्ट B-ट्री इंडेक्स में मनमानी जगहों पर गिरते हैं — पेज बँटते हैं, इंडेक्स बिखरता है, और बड़े टेबल पर लिखने की क्षमता नापने लायक़ गिर जाती है। v7 UUID मिलीसेकंड टाइमस्टैम्प से शुरू होता है, इसलिए इंसर्ट ऑटो-इंक्रीमेंट पूर्णांक की तरह आख़िर में जुड़ते जाते हैं और वैश्विक विशिष्टता भी बनी रहती है। UUID की चाहिए तो v7 लीजिए। दूसरी क़ीमत दोनों पर लागू होती है: पूर्णांक के 4 या 8 बाइट के मुक़ाबले 16 बाइट, और वह भी हर उस इंडेक्स में जो इसका ज़िक्र करता है।

    UUID v7 क्या है और क्या इसे अभी इस्तेमाल करना ठीक है?

    यह समय के क्रम में होता है: Unix मिलीसेकंड के 48 बिट और उसके बाद 74 यादृच्छिक बिट; मई 2024 में RFC 9562 में इसका मानकीकरण हुआ। यह प्रकाशित मानक है और मौजूदा Postgres में, ज़्यादातर भाषाओं के तंत्र में और अच्छी-ख़ासी लाइब्रेरियों में समर्थित है। नए काम के लिए यह वाजिब डिफ़ॉल्ट है। ध्यान रखने लायक़ एक गुण यह है कि इसमें बनने का समय जड़ा होता है, इसलिए किसी URL में मौजूद v7 पहचानकर्ता मोटे तौर पर बता देता है कि रिकॉर्ड कब बना था।

    क्या UUID इतना सुरक्षित है कि उसे टोकन बनाया जाए?

    क्रिप्टोग्राफ़िक स्रोत से बना v4 UUID 122 बिट एंट्रॉपी रखता है, जो पासवर्ड रीसेट लिंक या सेशन पहचानकर्ता के लिए ज़रूरत से ज़्यादा है। दो शर्तें हैं। पहली, स्रोत सचमुच क्रिप्टोग्राफ़िक होना चाहिए — crypto.randomUUID है, ज़्यादातर लाइब्रेरी कार्यान्वयन हैं, और Math.random() पर बनी हर चीज़ नहीं है। दूसरी, बाक़ी वर्शन इस काम के नहीं हैं: v1 में टाइमस्टैम्प जड़ा होता है और ऐतिहासिक रूप से MAC पता भी, v3 और v5 अपने इनपुट के निर्धारित हैश हैं, और v7 अपना बनने का समय बता देता है। अगर उसका अनुमान लगाना नामुमकिन होना चाहिए तो v4 लीजिए।

    UUID सिर्फ़ 16 बाइट का है तो 36 अक्षर का क्यों दिखता है?

    क्योंकि उसे हेक्साडेसिमल में लिखा जाता है — हर बाइट के दो अक्षर, यानी 32 — और साथ में चार हाइफ़न। कुछ सिस्टम इसकी जगह 16 कच्चे बाइट सहेजते हैं, MySQL का BINARY(16) इसी के लिए है और इससे भंडारण लगभग आधा रह जाता है। कुछ और छोटी टेक्स्ट एन्कोडिंग इस्तेमाल करते हैं: Base64 से 22 अक्षर बनते हैं, Base32 से 26 और वह छोटे-बड़े अक्षरों में फ़र्क़ नहीं करता। ये सब वही 128 बिट हैं, बस कपड़े अलग हैं।

    अंतिम समीक्षा । कुछ पुराना पड़ा हुआ मिला? हमें बताइए.