Little random string generator that unfortunately sometimes fails. Please help me fix it
From some StackOverflow answer I have that neat little function to generate a 10 character String with only a-z and 0-9 chars:
rand(36**10).to_s(36)
The problem is that it sometimes fails and only generates 9 characters.开发者_如何转开发 But I really like the ease and speed of it. Any suggestions how to fix it so that I can be sure that it always generates exactly 10 characters? (Without any loops or checking.)
When you randomly generate a number less than 369, it ends up being a 9-character string. Left-pad it with zeros:
rand(36**10).to_s(36).rjust(10, "0")
Example:
irb(main):018:0> (36**9).to_s(36)
=> "1000000000"
irb(main):019:0> (36**9 - 1).to_s(36)
=> "zzzzzzzzz"
irb(main):020:0> (36**5).to_s.rjust(10, "0")
=> "0060466176"
how about:
>> require 'md5'
=> true
>> MD5::hexdigest(Time.now.to_f.to_s)[0..9]
=> "89d83d3516"
This will generate a random string of characters and numbers but no single character will appear more than once
(('a'..'z').to_a + (0..9).to_a).shuffle[1..10].join
To "fix" the number of possible outcomes you just do this:
a = (('a'..'z').to_a + (0..9).to_a)
a = a * 10
p a.shuffle[1..10].join
Starting with the idea of using rand(36**5)
by @Mark Rushakoff, this shuffles the zero-padded string to randomize the characters:
('%010x' % [rand(36**5)]).chars.to_a.shuffle.join # => "4a04020701"
('%010x' % [rand(36**5)]).chars.to_a.shuffle.join # => "0e092f0a03"
('%010x' % [rand(36**5)]).chars.to_a.shuffle.join # => "03e240e800"
To work around Ruby not allowing zero-padded strings in the format
I have to switch to padding in the method chain, which is basically what Mark did. To avoid strings of leading zeros this breaks it back down to an array and shuffles the string and rejoins it.
rand(36**5).to_s(36).rjust(10, '0').chars.to_a.shuffle.join # => "e80000h00b"
rand(36**5).to_s(36).rjust(10, '0').chars.to_a.shuffle.join # => "00bv0dy00p"
rand(36**5).to_s(36).rjust(10, '0').chars.to_a.shuffle.join # => "v0hw000092"
(('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a).sample(8).join
精彩评论