2011-05-06 14 views
5

में अद्वितीय छः अंक अल्फा-न्यूमेरिक कोड कैसे उत्पन्न करें मुझे एक अद्वितीय छह अंकों वाला अल्फा-न्यूमेरिक कोड उत्पन्न करने की आवश्यकता है। वाउचर संख्या के रूप में मेरे डेटाबेस में सहेजने के लिए: प्रत्येक लेनदेन के लिए।रुबी

+2

आप कोड को स्वतः बढ़ाना क्यों नहीं कर रहे हैं? वे तब संख्यात्मक होंगे। यदि आपके पास बहुत से कोड हैं (6 अंकों से अधिक), तो आप इस नंबर के बेस 32 एन्कोडिंग का उपयोग कर सकते हैं, उदा। – Jens

+0

संभावित डुप्लिकेट? http://stackoverflow.com/questions/88311/how-best-to-generate-a-random-string-in-ruby – Teoulas

+0

@Teoulas मुझे ऐसा नहीं लगता है। इस प्रश्न में कुछ भी नहीं है जो कहता है कि कोड को यादृच्छिक (या प्रकट) होना चाहिए। – Phrogz

उत्तर

3

मैं इस्तेमाल किया इस

require 'sha1' 
    srand 
    seed = "--#{rand(10000)}--#{Time.now}--" 
    Digest::SHA1.hexdigest(seed)[0,6] 

How to generate a random string in Ruby यह लिंक उपयोगी था

+1

टकराव की उच्च संभावना के साथ यह एक बहुत बुरा जवाब है। 21 लाख हज़ार कुंजियों पर 1 मिलियन पुनरावृत्तियों के साथ 767 ** हजार ** टकराव हैं। '10000' से' 10000000' तक यादृच्छिक संख्या को टक्कर मारने से टकराव को 1,000,000 में से केवल "31,000" तक कम कर दिया जाता है, लेकिन कोई भी टक्कर अभी भी खराब है। यह सच है कि समय .now हमेशा एक जैसा होता है या यदि यह प्रत्येक कॉल का एक नया मूल्य देता है (उदा। प्रति सेकंड एक से अधिक लेनदेन नहीं)। – Phrogz

+0

सामान्य मामले में यह एक स्वीकार्य है। इसके लिए कोई और तरीका है। – rubyprince

0

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

+0

यह सिद्धांत में एक बुरा विचार है क्योंकि आप उपलब्ध नामस्थान को भरना शुरू करते हैं, क्योंकि टकराव की संभावना बढ़ जाती है और चरम पर आप एक मुफ्त कुंजी खोजने से पहले बहुत लंबे समय तक पुन: उत्पन्न करने के लूप में फंस जाते हैं। – Phrogz

0

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

class AlnumKey 

    def initialize 
    @chars = ('0' .. '9').to_a + ('a' .. 'z').to_a 
    end 

    def to_int(key) 
    i = 0 
    key.each_char do |ch| 
     i = i * @chars.length + @chars.index(ch) 
    end 
    i 
    end 

    def to_key(i) 
    s = "" 
    while i > 0 
     s += @chars[i % @chars.length] 
     i /= @chars.length 
    end 
    s.reverse 
    end 

    def next_key(last_key) 
    to_key(to_int(last_key) + 1) 
    end 
end 

al = AlnumKey.new 
puts al.next_key("ab") 
puts al.next_key("1") 
puts al.next_key("zz") 
बेशक

, आप अपने वर्तमान कुंजी संग्रहीत करना होगा कहीं, और इस कोई रास्ता सूत्र में है/multisession सुरक्षित आदि

0
निम्नलिखित प्रतिबंधों के साथ

:

  1. मान्य केवल 2038/12/24 00:40:35 यूटीसी
  2. जब तक एक दूसरे

आप इस सरल उपयोग कर सकते हैं के भीतर एक बार से अधिक उत्पन्न करता है कोड:

Time.now.to_i.to_s(36) 
# => "lks3bn" 
+2

सिस्टम समय बदलने पर क्या होगा? – Zabba

+0

एक समय में मुझे अलग वाउचर आईडी की –

+0

@ ज़ब्बा प्राप्त करने की आवश्यकता है जो एक समस्या का कारण बनता है, लेकिन मुझे लगता है कि यह इतनी बार नहीं होगी। उस स्थिति में, सिस्टम को समय अवधि के लिए रखरखाव के लिए नीचे रहना होगा जो नए और पुराने समय क्षेत्रों के बीच अंतर के बराबर होगा। यह एक दिन से भी कम समय में सबसे खराब होगा। यदि नया समय क्षेत्र आगे बढ़ता है, तो सिस्टम को नीचे नहीं होना चाहिए। – sawa

0
class IDSequence 
    attr_reader :current 
    def initialize(start=0,digits=6,base=36) 
    @id, @chars, @base = start, digits, base 
    end 
    def next 
    s = (@id+=1).to_s(@base) 
    @current = "0"*(@chars-s.length) << s 
    end 
end 

id = IDSequence.new 
1234.times{ id.next } 

puts id.current 
#=> 0000ya 

puts id.next 
#=> 0000yb 

9876543.times{ id.next } 
puts id.current 
#=> 05vpqq 
0

यह eleviat हैं और मिली सेकंड प्राप्त करके समय टकराव का मुद्दा

(Time.now.to_f*1000.0).to_i