Reputation: 16075
I need to generate a unique six digit alpha-numeric code. To save in my database as voucher no: for every transaction.
Upvotes: 5
Views: 6265
Reputation: 6864
This would eleviate the time collision issue by getting the milli seconds
(Time.now.to_f*1000.0).to_i
Upvotes: 0
Reputation: 303450
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
Upvotes: 0
Reputation: 168239
With the following restrictions:
you can use this simple code:
Time.now.to_i.to_s(36)
# => "lks3bn"
Upvotes: 0
Reputation: 16075
I used this
require 'sha1'
srand
seed = "--#{rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,6]
How to generate a random string in Ruby This link was useful
Upvotes: 3
Reputation: 30835
I'd use the database to generate unique keys, but if you insist on doing it the hard way:
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")
Of course, you'll have to store your current key somewhere, and this is in no way thread / multisession-safe etc.
Upvotes: 0
Reputation: 18028
A better way is to let the database handle the ids(incrementing). But if you insisting on generating them your self, you can use a random generator to generate an code, check it against db for uniqueness. then either accept or regenerate
Upvotes: 0