2008-10-10 15 views
16

मैं गुड्स/यूआईडी के मानवीय पठनीय विकल्पों पर एक छोटा सा लेख लिख रहा हूं, उदाहरण के लिए जो यूआरएल हैश के लिए TinyURL पर उपयोग किए जाते हैं (जिन्हें अक्सर पत्रिकाओं में मुद्रित किया जाता है, इसलिए संक्षिप्त होने की आवश्यकता होती है)।अपनी खुद की Tinyurl शैली बनाना uid

मैं उत्पन्न करने वाला सरल यूआईडी है - 6 वर्ण: या तो लोअरकेस अक्षर (ए-जेड) या 0-9।

"मेरी गणना कप्तान के अनुसार", यह 6 पारस्परिक रूप से अनन्य घटनाओं की है, हालांकि संघर्ष की संभावना की गणना करना पी (ए या बी) = पी (ए) + पी (बी) से थोड़ा कठिन हो जाता है, जैसा कि जाहिर है संख्याओं और नीचे दिए गए कोड से, आप देख सकते हैं कि यह 50/50 का उपयोग करके किसी संख्या या अक्षर का उपयोग करना है या नहीं।

मुझे संघर्ष दर में रूचि है और यदि नीचे दिया गया कोड अनुमानित संघर्ष दर का यथार्थवादी सिमुलेशन है जो आपको हैश उत्पन्न करने से प्राप्त होता है। औसतन मुझे प्रति मिलियन 40-50 संघर्ष मिलते हैं, हालांकि ध्यान में रखते हुए कि यूआईडी एक बार में दस लाख बार उत्पन्न नहीं किया जाएगा, लेकिन शायद एक मिनट में लगभग 10-1000 बार।

हर बार संघर्ष की संभावना क्या है, और क्या कोई इसे करने का बेहतर तरीका सुझा सकता है?

static Random _random = new Random(); 

public static void main() 
{ 
    // Size of the key, 6 
    HashSet<string> set = new HashSet<string>(); 
    int clashes = 0; 
    for (int n=0;n < 1000000;n++) 
    { 
     StringBuilder builder = new StringBuilder(); 

     for (int i =0;i < 7;i++) 
     { 
      if (_random.NextDouble() > 0.5) 
      { 
       builder.Append((char)_random.Next(97,123)); 
      } 
      else 
      { 
       builder.Append(_random.Next(0,9).ToString()); 
      } 
     } 

     if (set.Contains(builder.ToString())) 
     { 
      clashes++; 
      Console.WriteLine("clash: (" +n+ ")" +builder.ToString()); 
     } 

     set.Add(builder.ToString()); 
     _random.Next(); 
     //Console.Write(builder.ToString()); 
    } 

    Console.WriteLine("Clashes: " +clashes); 
    Console.ReadLine(); 
} 

अद्यतन: Here's the resulting article इस सवाल

से मैं सच में दो सवाल पूछा यहाँ तो मैं धोखा दे रहा था। जवाब मैं बाद में राकर था, हालांकि स्क्लिवज़ भी दूसरे भाग (एक वैकल्पिक) का जवाब है। क्या डेटाबेस में एक कस्टम अद्वितीय आईडी जेनरेटर बनाना संभव है, या यह क्लाइंट साइड होगा (जो 2 संभवतः पहले संभव होगा)?

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

अद्यतन 2: मैं (बजाय 2 स्वतंत्र लोगों के ऊपर दो परस्पर अनन्य घटनाओं के लिए सूत्र डाल एक 'एक' पहली बार मतलब यह नहीं है कि आप एक 'एक' दूसरी बार नहीं मिल सकता है हो रही है के रूप में)। पी (ए और बी) = पी (ए) एक्स पी (बी)

उत्तर

4

एक विशिष्ट आईडी के खिलाफ एक टक्कर की संभावना है:

p = (0.5 * ((0.5*1/10) + (0.5*1/26)))^6 

जो चारों ओर 1.7 × 10^है -9।

एन आईडी उत्पन्न करने के बाद टकराव की संभावना 1-पी^एन है, इसलिए आपके पास 10 मिलियन आईडी डालने के बाद प्रत्येक नए सम्मिलन के लिए टकराव का लगभग 0.17% मौका होगा, लगभग 10% के बाद 1.7% मिलियन आईडी, और 100 मिलियन के बाद लगभग 16%।

1000 आईडी/मिनट लगभग 43 मिलियन/माह तक काम करता है, इसलिए स्किलीवज़ ने बताया कि कुछ वृद्धिशील आईडी का उपयोग करने से शायद इस मामले में जाने का बेहतर तरीका होगा।

संपादित करें:

गणित समझाने के लिए, वह अनिवार्य रूप से एक सिक्का flipping है और फिर एक संख्या या अक्षर 6 बार उठा। सिक्का फ्लिप मैचों की एक 0.5 संभावना है, और उसके बाद 50% समय मिलान करने का 1/10 मौका है और मिलान के 1/26 मौके का 50% मौका है। यह स्वतंत्र रूप से 6 गुना होता है, इसलिए आप उन संभावनाओं को एक साथ गुणा करते हैं।

+0

आईडी को हैश करने का बुरा विचार - आपको पंक्ति को देखने के लिए वापस अनचाहे आईडी प्राप्त करने की आवश्यकता है। Sklivvz जवाब देखें। – MSalters

+0

मुझे नहीं लगता कि आपके गणित काफी सही हैं। ओपी का डेटा प्रति मिलियन ~ 50 टकराव सुझाता है, जबकि आप 1700 (1000000 का 0.17%) की भविष्यवाणी करते हैं। शायद मुझे कुछ याद आ रहा है? – freespace

+0

मेरा मतलब वास्तविक हश नहीं था; मैं बस Sklivvz के जवाब का पालन करना था। मैं इसे स्पष्ट करने के लिए अपना उत्तर संपादित करूंगा। – Randy

6

Birthday Paradox देखें, यह सही समस्या है जिसमें आप चल रहे हैं।

सवाल यह है: कितने लोगों को आप, ताकि आप एक ही जन्मतिथि होने किसी भी दो लोगों के एक 50% मौका है एक कमरे में एक साथ पाने के लिए की जरूरत है? जवाब आपको आश्चर्य में डाल सकता है।

0

क्यों एक हैशिंग एल्गोरिदम का उपयोग न करें? और यूआरएल के हैश का उपयोग करें?

यदि आप यादृच्छिक संख्या संभावना का उपयोग कर रहे हैं क्योंकि वे अनिश्चित हैं आप संघर्ष मिल जाएगा रहे हैं।

हैश proovably अद्वितीय नहीं हैं लेकिन वहाँ एक काफी अच्छा मौका है कि एक स्ट्रिंग के हैश अद्वितीय हो जाएगा।

सुधार

वास्तव में आप उन्हें आदमियत पठनीय होने के लिए ... अगर तुम उन्हें हेक्स में डाल वे तकनीकी रूप से आदमियत पठनीय हैं चाहते प्रतीक्षा करें।

या आप एक एल्गोरिथ्म है कि एक आदमियत पठनीय स्ट्रिंग में एक हैश परिवर्तित इस्तेमाल कर सकते हैं। अगर आदमियत पठनीय स्ट्रिंग हैश यह भी रूप में हैश, मूल हैश की यानी आधार के रूप में 36 "अद्वितीय" होना चाहिए की एक अलग प्रतिनिधित्व है।

+0

मुझे लगता है कि बिंदु यह है कि यह सिर्फ अनुकरण करता है लेकिन वास्तविक हैशिंग एल्गोरिदम नहीं है। ऐसा इसलिए वह टक्कर दर की तरह मेट्रिक्स निर्धारित कर सकता है। – mattlant

31

आप एक यादृच्छिक फ़ंक्शन का उपयोग क्यों करना चाहते हैं? मुझे हमेशा लगता है कि tinyurl अनुक्रमिक आईडी के आधार 62 (0-9 ए-जेए-जेड) प्रतिनिधित्व का उपयोग करता है। कोई संघर्ष नहीं और यूआरएल हमेशा जितना संभव हो उतना छोटा होता है।

आप

Id URL 
1 http://google.com 
2 ... 
... ... 
156 ... 
... ... 

की तरह एक डीबी तालिका होगा और संबंधित URL होगा:

http://example.com/1 
http://example.com/2 
... 
http://example.com/2W 
... 
+0

मुझे लगता है कि बिंदु यह है कि यह सिर्फ अनुकरण करता है लेकिन वास्तविक हैशिंग एल्गोरिदम नहीं है। ऐसा इसलिए वह टक्कर दर की तरह मेट्रिक्स निर्धारित कर सकता है। – mattlant

+1

मैंने अभी तक बेस 62 के बारे में नहीं सुना था! जैसा कि आपने ऊपर रखा है, कुंजी के बेस 62 संस्करण को संग्रहीत करने के बजाय बेस 62 से डीकोडिंग करने के सटीक तरीके की तरह लगता है। –

+2

मुझे संदेह है कि TinyURL आधार 36 या कम से कम आधार एन का उपयोग करता है जहां एन < 62 and N > = 36. मुझे नहीं लगता कि वे आपको निम्न मामले और ऊपरी केस वर्णों का उपयोग करने देते हैं। यदि आप फोन पर किसी के द्वारा निर्धारित किए जाने पर यूआरएल दर्ज करना आसान होना चाहते हैं, तो आप केस-सेंसिटिव अनुक्रम नहीं चाहते हैं। –

0

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

0

यदि आप 6 वर्ण, ए-जेड और 0-9 का उपयोग कर रहे हैं, तो कुल 36 वर्ण हैं। क्रमपरिवर्तन की संख्या 36^6 है जो 2176782336 है .. इसलिए इसे केवल 1/2176782336 बार संघर्ष करना चाहिए।

+0

क्या मेरे गणित गलत हैं? – Ryan

+0

हां, क्योंकि पात्र समान रूप से वितरित नहीं होते हैं। एक (वास्तव में खराब) एल्गोरिदम पर विचार करें: यदि आप एक डी 100 रोल करते हैं और परिणाम बिल्कुल 42 है, तो बहुत लंबा GUID उत्पन्न करें। अन्यथा, परिणाम = "दोह"। संभावित हैश की संख्या: भारी। संघर्ष की संभावना? विशाल! –

+1

@ जोन: किसी भी उचित हैश एल्गोरिदम में भी वितरण होगा। @Ryan: यदि आपकी क्वेरी 2 हैश मान उत्पन्न करती है, तो आपकी गणना सही है, तो उन्हें टकराव की संभावना क्या है? "। हालांकि यहां प्रश्न पहले उत्पन्न मूल्यों को बरकरार रखता है, इसलिए गणित इतना आसान नहीं है। – freespace

0
wikipedia से

:

जब कम वर्ण वांछित है मुद्रण, GUIDs कभी कभी एक बेस 64 या Ascii85 स्ट्रिंग में इनकोड। Base64- एन्कोड GUID, 22 से 24 वर्ण (गद्दी के आधार पर) के होते हैं, उदाहरण के लिए:

7QDBkvCA1+B9K/U0vrQx1A 
7QDBkvCA1+B9K/U0vrQx1A== 

और Ascii85 एन्कोडिंग केवल 20 वर्ण देता है, ई। ग्राम .:

5:$Hj:Pf\4RLB9%kU\Lj 

तो अगर आप विशिष्टता के साथ संबंध है, एक बेस 64 इनकोडिंग GUID आप, कुछ हद तक आप क्या चाहते हैं के करीब हो जाता है इसकी नहीं 6 अक्षर हालांकि।

बाइट्स में पहले काम करना सबसे अच्छा है, फिर उन बाइट्स को सीधे वर्णों के साथ काम करने के बजाय प्रदर्शन के लिए हेक्साडेसिमल में अनुवाद करें।

5

कुछ समय पहले मैंने यह बिल्कुल किया था, और स्किलीवज़ ने जिस तरह से इसका उल्लेख किया था, मैंने इसका अनुसरण किया। संपूर्ण तर्क एक SQL सर्वर संग्रहीत प्रक्रिया और कुछ यूडीएफ (उपयोगकर्ता परिभाषित कार्यों) के साथ विकसित किया गया था। चरणों थे:

  • का कहना है कि आप इस यूआरएल को छोटा करना चाहते हैं: Creating your own Tinyurl style uid
  • एक मेज
  • पिछले डालने की @@ पहचान मूल्य (एक अंकीय आईडी)
  • प्राप्त में URL डालें
  • वापसी कि वापस महत्व देते हैं, कुछ 'CC0'
तरह: एक इसी अक्षरांकीय मूल्य, एक अक्षरों और संख्याओं का "डोमेन" पर आधारित में आईडी रूपांतरण ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" मैं वास्तव में इस सेट का इस्तेमाल किया)

रूपांतरण को बहुत कम यूडीएफ के माध्यम से महसूस किया गया था।

दो रूपांतरण एक के बाद एक कहा जाता वापसी होगी "अनुक्रमिक" इस तरह के मूल्यों:

select dbo.FX_CONV (123456) -- returns "1f5n" 

select dbo.FX_CONV (123457) -- returns "1f5o" 

आप मैं यूडीएफ के कोड साझा कर सकते हैं रुचि रखते हैं।

+0

क्या आप यूडीएफ कोड साझा कर सकते हैं? –

+1

यही कारण है कि किसी को भी कभी नहीं पूछना चाहिए "क्या मुझे कोड साझा करना चाहिए?" और उन्हें सिर्फ कोड साझा करना चाहिए। यह 5 साल से अधिक हो गया है और केएमन अभी भी इंतजार कर रहा है। –

संबंधित मुद्दे