How to generate a random string in Ruby
(0...8).map { (65 + rand(26)).chr }.join
I spend too much time golfing.
(0...50).map { ('a'..'z').to_a[rand(26)] }.join
And a last one that's even more confusing, but more flexible and wastes fewer cycles:
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[rand(o.length)] }.join
If you want to generate some random text then use the following:
50.times.map { (0...(rand(10))).map { ('a'..'z').to_a[rand(26)] }.join }.join(" ")
this code generates 50 random word string with words length less than 10 characters and then join with space
How to generate a random string in Ruby
(0...8).map { (65 + rand(26)).chr }.join
I spend too much time golfing.
(0...50).map { ('a'..'z').to_a[rand(26)] }.join
And a last one that's even more confusing, but more flexible and wastes fewer cycles:
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[rand(o.length)] }.join
If you want to generate some random text then use the following:
50.times.map { (0...(rand(10))).map { ('a'..'z').to_a[rand(26)] }.join }.join(" ")
this code generates 50 random word string with words length less than 10 characters and then join with space
Generate pseudo random string A-Z, 0-9
Array.new(n){[*"A".."Z", *"0".."9"].sample}.join
How would i generate a random and unique string in Ruby?
I use this :)
def generate_token(column, length = 64)
begin
self[column] = SecureRandom.urlsafe_base64 length
end while Model.exists?(column => self[column])
end
Replace Model
by your model name
Generate Unique Random String With Letters And Numbers In Lower Case
If you are using ruby 1.9.2 you can use SecureRandom:
irb(main):001:0> require 'securerandom'
=> true
irb(main):002:0> SecureRandom.hex(13)
=> "5bbf194bcf8740ae8c9ce49e97"
irb(main):003:0> SecureRandom.hex(15)
=> "d2413503a9618bacfdb1745eafdb0f"
irb(main):004:0> SecureRandom.hex(32)
=> "432e0a359bbf3669e6da610d57ea5d0cd9e2fceb93e7f7989305d89e31073690"
How to generate a random string in rails
You can have your f.input as such
<%= f.text_field :name, id: :bug_name, value: "#{SecureRandom.hex(64)}" %>
Unique random string with alphanumberic required in Ruby
down = ('a'..'z').to_a
up = ('A'..'Z').to_a
digits = ('0'..'9').to_a
all = down + up + digits
[down.sample, up.sample, digits.sample].
concat(7.times.map { all.sample }).
shuffle.
join
#=> "TioS8TYw0F"
[Edit: The above reflects a misunderstanding of the question. I'll leave it, however. To have no characters appear more than once:
def rnd_str
down = ('a'..'z').to_a
up = ('A'..'Z').to_a
digits = ('0'..'9').to_a
[extract1(down), extract1(up), extract1(digits)].
concat(((down+up+digits).sample(7))).shuffle.join
end
def extract1(arr)
i = arr.size.times.to_a.sample
c = arr[i]
arr.delete_at(i)
c
end
rnd_str #=> "YTLe0WGoa1"
rnd_str #=> "NrBmAnE9bT"
down.sample.shift
(etc.) would have been more compact than extract1
, but the inefficiency was just too much to bear.
If you do not want to repeat random strings, simply keep a list of the ones you generate. If you generate another that is in the list, discard it and generate another. It's pretty unlikely you'll have to generate any extra ones, however. If, for example, you generate 100 random strings (satisfying the requirement of at least one lowercase letter, uppercase letter and digit), the chances that there will be one or more duplicate strings is about one in 700,000:
t = 107_518_933_731
n = t+1
t = t.to_f
(1.0 - 100.times.reduce(1.0) { |prod,_| prod * (n -= 1)/t }).round(10)
#=> 1.39e-07
where t = C(62,10)
and C(62,10)
is defined below.
An alternative
There is a really simple way to do this that turns out to be pretty efficient: just sample without replacement until a sample is found that meets the requirement of at least lowercase letter, one uppercase letter and one digit. We can do that as follows:
DOWN = ('a'..'z').to_a
UP = ('A'..'Z').to_a
DIGITS = ('0'..'9').to_a
ALL = DOWN + UP + DIGITS
def rnd_str
loop do
arr = ALL.sample(10)
break arr.shuffle.join unless (DOWN&&arr).empty? || (UP&&arr).empty? ||
(DIGITS&&arr).empty?
end
end
rnd_str #=> "3jRkHcP7Ge"
rnd_str #=> "B0s81x4Jto
How many samples must we reject, on average, before finding a "good" one? It turns out (see below if you are really, really interested) that the probability of getting a "bad" string (i.e, selecting 10 characters at random from the 62 elements of all
, without replacement, that has no lowercase letters, no uppercase letters or no digits, is only about 0.15. (15%). That means that 85% of the time no bad samples will be rejected before a good one is found.
It turns out that the expected number of bad strings that will be sampled, before a good string is sampled, is:
0.15/0.85 =~ 0.17
The following shows how the above probability was derived, should anyone be interested.
Let n_down
be the number of ways a sample of 10 can be drawn that has no lowercase letters:
n_down = C(36,10) = 36!/(10!*(36-10)!)
where (the binomial coefficient) C(36,10)
equals the number of combinations of 36 "things" that can be "taken" 10 at a time, and equals:
C(36,10) = 36!/(10!*(36-10)!) #=> 254_186_856
Similarly,
n_up = n_down #=> 254_186_856
and
n_digits = C(52,10) #=> 15_820_024_220
We can add these three numbers together to obtain:
n_down + n_up + n_digits #=> 16_328_397_932
This is almost, but not quite, the number of ways to draw 10 characters, without replacement, that contains no lowercase letters characters, uppercase letters or digits. "Not quite" because there is a bit of double-counting going on. The necessary adjustment is as follows:
n_down + n_up + n_digits - 2*C(26,10) - 3
#=> 16_317_774_459
To obtain the probability of drawing a sample of 10 from a population of 62, without replacement, that has no lowercase letter, no uppercase letter or no digit, we divide this number by the total number of ways 10 characters can be drawn from 62 without replacement:
(16_317_774_459.0/c(62,10)).round(2)
#=> 0.15
Generate random string from key
I am assuming from your question that you want for some reason to associate an input string to a random-looking output, and to have it be the same output if the same key is presented.
The code below will generate the same "random" string for the same input secret key, accepting keys up to 8 * 624 = 4992 bytes long. Technically this is not random, but using Ruby's built in random number generator to hash the input string.
def rand_hash secret_key
int_key = secret_key.unpack("C*").each_with_index.inject(0) do |sum, (byte, index)|
sum + byte * (256 ** index)
end
r = Random.new( int_key )
(0...50).map { ('a'..'z').to_a[ r.rand(26) ] }.join
end
rand_hash "Hi, how are you today?"
# => "mwerzokwwtlqepizuqimbhxmzexmovzrwgvarjlfbkcqpffhoq"
rand_hash "Hi, how are you today?"
# => "mwerzokwwtlqepizuqimbhxmzexmovzrwgvarjlfbkcqpffhoq"
rand_hash "Hi, how are you today!"
# => "zeudwqltlozjdebamemplwllqftmyhdzapatqhdsbnrzfcrmss"
See How do I unpack a number larger than 64 bits in ruby? for how the secret_key
is unpacked from a string into a BigNum called int_key
.
We then use that key to seed a Ruby Random
object (based on Mersenne Twister)
Then use the new Random
object to generate the string, same as you do originally.
Note this is not cryptographically secure. If you want security, such as impossibility to reverse the output and find the secret, then you should use a secure hash mechanism (from an appropriate gem such as openssl
), and convert that to the character set you require.
customised random string generator in ruby
Try this:
def gen_pass(lengths, number_of_numbers, number_of_special_chars)
chars = ('a'..'z').to_a + ('A'..'Z').to_a + (0..10).to_a
digits = (0..9).to_a
special_chars = "?<>',?[]}{=-)(*&^%$#`~{}".split('')
remaining_letters_count = lengths - number_of_numbers - number_of_special_chars
n = digits.sample(number_of_numbers)
s = special_chars.sample(number_of_special_chars)
c = chars.sample(remaining_letters_count)
str = n << s << c
str.flatten.shuffle.join
end
puts gen_pass(lengths, number_of_numbers, number_of_special_chars)
Related Topics
How to Remove Rvm (Ruby Version Manager) from My System
How to Pick Randomly from an Array
How to Find and Return a Duplicate Value in Array
How to Install Sqlite3 For Ruby on Windows
How to Create an Average from a Ruby Array
String Concatenation Vs. Interpolation in Ruby
Creating Matrix With 'Array.New(N, Array.New)'
Ruby/Ruby on Rails Memory Leak Detection
Unexpected Keyword_End Error, Yet Syntax Seems Fine
What Do 'I' and '-I' in Regex Mean
Understanding the Rails Authenticity Token
Combining Implicit Wait and Explicit Wait Together Results in Unexpected Wait Times
How to Download a Binary File Over Http
How to Create a Deep Copy of an Object in Ruby
Using Rails Serialize to Save Hash to Database
Ruby'S Double Colon (::) Operator Usage Differences