निर्धारक मार्गदर्शिकाएँ कैसे बनाएँ


103

हमारे आवेदन में हम Xml फाइलें एक विशेषता के साथ बना रहे हैं, जिसमें एक दिशानिर्देश मूल्य है। फ़ाइल अपग्रेड के बीच संगत होना आवश्यक है। इसलिए भले ही फ़ाइल में बाकी सब कुछ बदल जाए, लेकिन विशेषता के लिए गाइड मूल्य समान रहना चाहिए।

एक स्पष्ट समाधान उनके लिए इस्तेमाल किए जाने वाले फ़ाइलनाम और गाइड के साथ एक स्थिर शब्दकोश बनाना था। फिर जब भी हम फ़ाइल जनरेट करते हैं, तो हम फ़ाइल नाम के लिए शब्दकोश को देखते हैं और संबंधित गाइड का उपयोग करते हैं। लेकिन यह संभव नहीं है, क्योंकि हम 100 की फाइलों के पैमाने पर हो सकते हैं और कुछ छापों की बड़ी सूची को बनाए नहीं रखना चाहते।

इसलिए एक अन्य तरीका यह था कि गाइड को फाइल के पथ के आधार पर समान बनाया जाए। चूंकि हमारी फ़ाइल पथ और एप्लिकेशन निर्देशिका संरचना अद्वितीय हैं, इसलिए उस पथ के लिए मार्गदर्शिका अद्वितीय होनी चाहिए। इसलिए हर बार जब हम अपग्रेड चलाते हैं, तो फ़ाइल को उसी पथ पर आधारित गाइड मिलती है। मुझे इस तरह के ' निर्धारक मार्गदर्शक ' (धन्यवाद एल्टन स्टोनमैन) को उत्पन्न करने के लिए एक अच्छा तरीका मिला । यह मूल रूप से ऐसा करता है:

private Guid GetDeterministicGuid(string input) 

{ 

//use MD5 hash to get a 16-byte hash of the string: 

MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider(); 

byte[] inputBytes = Encoding.Default.GetBytes(input); 

byte[] hashBytes = provider.ComputeHash(inputBytes); 

//generate a guid from the hash: 

Guid hashGuid = new Guid(hashBytes); 

return hashGuid; 

} 

तो एक तार दिया, गाइड हमेशा एक ही रहेगा।

क्या ऐसा करने के लिए कोई अन्य दृष्टिकोण या अनुशंसित तरीके हैं? उस विधि के पेशेवरों या विपक्ष क्या हैं?

जवाबों:


151

जैसा कि @bacar द्वारा उल्लेख किया गया है, RFC 4122 .34.3 एक नाम-आधारित UUID बनाने का एक तरीका निर्धारित करता है। ऐसा करने का लाभ (केवल एमडी 5 हैश का उपयोग करके) यह है कि इन्हें गैर-नाम-आधारित यूयूआईडी से टकराने की गारंटी नहीं है, और अन्य नाम-आधारित यूयूआईडी के साथ टकराव की बहुत (बहुत) छोटी संभावना है।

इन्हें बनाने के लिए .NET फ्रेमवर्क में कोई मूल समर्थन नहीं है, लेकिन मैंने GitHub पर कोड पोस्ट किया है जो एल्गोरिथ्म को लागू करता है। इसका उपयोग इस प्रकार किया जा सकता है:

Guid guid = GuidUtility.Create(GuidUtility.UrlNamespace, filePath);

आगे भी अन्य GUID के साथ टकराव के जोखिम को कम करने के लिए, आप नामस्थान आईडी (RFC में परिभाषित URL नामस्थान ID का उपयोग करने के बजाय) के रूप में उपयोग करने के लिए एक निजी GUID बना सकते हैं।


5
@Porges: RFC4122 गलत है और इसमें इरेटा है जो C कोड ( rfc-editor.org/errata_search.php?rfc=4122&eid=1352 ) को ठीक करता है । यदि यह कार्यान्वयन RFC4122 और इसके इरेटा के साथ पूरी तरह से अनुपालन नहीं है, तो कृपया आगे विवरण प्रदान करें; मैं इसे मानक का पालन करना चाहूंगा।
ब्रैडली ग्रिंगर

1
@ ब्रैडलीगिंगर: मैंने ध्यान नहीं दिया, धन्यवाद / खेद! मुझे हमेशा याद रखना चाहिए कि RFC पढ़ते समय इरेटा की जाँच करें ... :)
7:10 पर

3
@Porges: आपका स्वागत है / कोई समस्या नहीं है। यह दिमाग को चकरा देता है कि वे इरेटा के सुधारों के साथ RFC को इन-प्लेस अपडेट न करें। यहां तक ​​कि दस्तावेज़ के अंत में एक लिंक पाठक पर भरोसा करने से पहले इरेटा ( आरएफसी पर आधारित कार्यान्वयन लिखने से पहले उम्मीद है कि खोज करने के लिए याद करने की तुलना में अधिक सहायक होगा )।
ब्रैडली ग्रिंगर

1
@ ब्रैडलीगिंगर: यदि आप एचटीएमएल संस्करण का उपयोग करते हैं, तो इसमें हेडर से इरेटा का लिंक होता है, जैसे tools.ietf.org/html/rfc4122 । मुझे आश्चर्य है कि अगर HTML संस्करण में हमेशा रीडायरेक्ट करने के लिए एक ब्राउज़र एक्सटेंशन है ...
पोर्स

2
आपको इसे .NET .NET रेपो में योगदान देने पर विचार करना चाहिए: github.com/dotnet/coreclr/tree/master/src/mscorlib/src/System
नीलमणि

29

यह बाहरी विधानसभा को आयात किए बिना किसी भी स्ट्रिंग को एक गाइड में बदल देगा।

public static Guid ToGuid(string src)
{
    byte[] stringbytes = Encoding.UTF8.GetBytes(src);
    byte[] hashedBytes = new System.Security.Cryptography
        .SHA1CryptoServiceProvider()
        .ComputeHash(stringbytes);
    Array.Resize(ref hashedBytes, 16);
    return new Guid(hashedBytes);
}

एक अद्वितीय दिशानिर्देश उत्पन्न करने के लिए बहुत बेहतर तरीके हैं लेकिन यह एक स्ट्रिंग डेटा कुंजी को एक गाइड डेटा कुंजी में लगातार अपग्रेड करने का एक तरीका है।


फ़ेडरेटेड वितरण के लिए डेटाबेस में अद्वितीय पहचानकर्ता का उपयोग करते समय यह स्निपेट उपयोगी पाया गया।
ग्लेंनो

6
चेतावनी! यह कोड मान्य गाइड / यूयूआईडी (जैसा कि नीचे उल्लेख किया गया है, बैकर भी नहीं) उत्पन्न नहीं करता है। न तो संस्करण और न ही प्रकार फ़ील्ड सही तरीके से सेट किए गए हैं।
मार्कसचैबर

3
क्या यह SHA1 के बजाय MD5CryptoServiceProvider का उपयोग करने के लिए उतना प्रभावी नहीं होगा, क्योंकि MD5 पहले से ही 16 बाइट्स लंबाई में है?
ब्रेन2000

20

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

आरएफसी 4122 संस्करण 3 और 5 उपयोग md5 और SHA1 (क्रमशः) - UUIDs पर विशेष रूप से नियतात्मक (नाम-आधारित) UUIDs के लिए अनुमति देता है। अधिकांश लोग संभवतः संस्करण 4 से परिचित हैं, जो यादृच्छिक है। विकिपीडिया संस्करणों का एक अच्छा अवलोकन देता है। (ध्यान दें कि यहाँ 'शब्द' शब्द का उपयोग UUID के 'प्रकार' का वर्णन करता हुआ प्रतीत होता है - संस्करण 5 में सुपरसीड संस्करण नहीं है)।

वहाँ कुछ पुस्तकालयों के लिए संस्करण 3/5 UUIDs उत्पन्न करने के लिए प्रतीत हो रहा है, अजगर uuid मॉड्यूल , boost.uuid (C ++) और OSSP UUID सहित । (मैं किसी भी .net वाले के लिए नहीं देखा है)


1
यह वास्तव में मूल पोस्टर के बाद क्या है। UUID में स्ट्रिंग के साथ शुरू करने और इसे GUID में बदलने के लिए आपके पास पहले से ही एक एल्गोरिथम है। UUID संस्करण 3 में MD5 के साथ स्ट्रिंग हैश किया जाता है, जबकि संस्करण 5 में SHA1 के साथ इसे हैश किया जाता है। एक "गाइड" बनाने में महत्वपूर्ण बिंदु अन्य GUID के खिलाफ इसे "अद्वितीय" बनाना है। एल्गोरिथ्म दो बिट्स को निर्धारित करता है, जिसे सेट किया जाना चाहिए, साथ ही एक कुतरना 3 या 5 पर सेट होता है, यह निर्भर करता है कि यह संस्करण 3 या 5 है
इयान बॉयड

2
"संस्करण" शब्द के उपयोग के बारे में, RFC 4122 .14.1.3 बताता है: "संस्करण अधिक सटीक उप-प्रकार है, फिर से, हम संगतता के लिए शब्द बनाए रखते हैं।"
ब्रैडली ग्रिंगर

11
मैंने GHHub पर v3 और v5 GUIDs बनाने के लिए कुछ C # कोड पोस्ट किया: github.com/LogosBible/Logos.Utility/blob/master/src/…
ब्रैडली ग्रिंजर

@ ब्रैडलीगिंगर, मुझे एक चेतावनी-विस्तारित ऑपरेंड पर उपयोग की जाने वाली चेतावनी बिटवाइज़ या ऑपरेटर मिलती है; पहले एक छोटे अहस्ताक्षरित प्रकार पर कास्टिंग करने पर विचार करें
सेबस्टियन

1
यह ऑफ-टॉपिक हो रहा है! GitHub को व्यक्तिगत रूप से काम करने वाली बग रिपोर्ट पेश करने का सुझाव दें।
बैकर

3

आपको कक्षा के उदाहरणों Guid, और पहचानकर्ताओं के बीच अंतर करने की आवश्यकता है जो विश्व स्तर पर अद्वितीय हैं। एक "नियतात्मक मार्गदर्शिका" वास्तव में एक हैश है (जैसा कि आपके कॉल द्वारा दर्शाया गया है provider.ComputeHash)। Hashes के माध्यम से बनाई गई गाइड की तुलना में टकराव (एक ही हैश का उत्पादन करने के लिए हो रहे दो अलग-अलग स्ट्रिंग्स) की बहुत अधिक संभावना है Guid.NewGuid

तो आपके दृष्टिकोण के साथ समस्या यह है कि आपको इस संभावना के साथ ठीक होना होगा कि दो अलग-अलग रास्ते एक ही GUID का उत्पादन करेंगे। यदि आपको एक पहचानकर्ता की आवश्यकता है जो किसी भी दिए गए पथ स्ट्रिंग के लिए अद्वितीय है, तो सबसे आसान काम केवल स्ट्रिंग का उपयोग करना है । अगर आपको अपने उपयोगकर्ताओं से अस्पष्ट रहने के लिए स्ट्रिंग की आवश्यकता है, तो इसे एन्क्रिप्ट करें - आप ROT13 या कुछ और अधिक शक्तिशाली उपयोग कर सकते हैं ...

कुछ है कि GUID डेटाटाइप में एक शुद्ध GUID नहीं है भविष्य में रखरखाव की समस्याओं को जन्म दे सकता जूते की कोशिश ...


2
आप दावा करते हैं कि "हैशिंग में टकराव की अधिक संभावना है ... गाइड के माध्यम से बनाई गई गाइड की तुलना में। NewGuid।" क्या आप इसे विस्तार में बताने में सक्षम हैं? व्यू के गणितीय बिंदु से, बिट्स की एक सेट की संख्या समान हो सकती है, और MD5 और SHA1 दोनों क्रिप्टोग्राफिक हैश हैं, विशेष रूप से (आकस्मिक और जानबूझकर) हैश टक्कर की संभावना को कम करने के लिए डिज़ाइन किया गया है।
मार्कसचैबर

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

2

MD5 कमजोर है, मुझे विश्वास है कि आप SHA-1 के साथ भी ऐसा कर सकते हैं और बेहतर परिणाम प्राप्त कर सकते हैं।

BTW, सिर्फ एक व्यक्तिगत राय, एक md5 हैश ड्रेसिंग के रूप में एक GUID यह एक अच्छा GUID नहीं बनाता है। अपने स्वभाव से GUIDs निर्धारक नहीं होते हैं। यह एक धोखा की तरह लगता है। क्यों नहीं बस एक कुदाल एक कुदाल कहते हैं और सिर्फ एक स्ट्रिंग इनपुट की हैश गाया है। आप नई गाइड लाइन के बजाय इस लाइन का उपयोग करके ऐसा कर सकते हैं:

string stringHash = BitConverter.ToString(hashBytes)

आपके इनपुट के लिए धन्यवाद, लेकिन यह अभी भी मुझे एक स्ट्रिंग देता है, और मुझे एक GUID की तलाश है ...
Punit Vora

ठीक है, अपने हैश को "GUID" कहें, समस्या हल हो गई। या वास्तविक समस्या यह है कि आपको एक वस्तु की आवश्यकता है Guid?
user7116

काश यह इतना आसान होता .. :) लेकिन हाँ, मुझे एक 'GUID' ऑब्जेक्ट चाहिए
पुनीत वोरा

5
"उनके स्वभाव से GUIDs गैर नियतात्मक हैं" - यह GUID के कुछ प्रकार ('संस्करण') का केवल सच है। हालाँकि मैं मानता हूँ कि "एक md5 हैश को एक GUID के रूप में तैयार करना अन्य कारणों से एक अच्छा GUID नहीं है" जैसा कि @Bradley Grainger और @Rob Fonseca-Ensor द्वारा किया गया है, और इस प्रश्न का मेरा उत्तर है।
बैकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.