35

How can I fix this code so it generates unique random letters and numbers in lower case?

api_string = (0...32).map{65.+(rand(25)).chr}.join    

At the moment, it generates only letters.

3
  • 1
    The range for numbers is 48 to 57. These must be included in your range. Commented May 11, 2011 at 15:41
  • Thanks for the answer. Can you give an example so I can mark it as correct? Commented May 11, 2011 at 15:43
  • possible duplicate of How best to generate a random string in Ruby Commented Mar 25, 2015 at 8:20

12 Answers 12

85

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"
Sign up to request clarification or add additional context in comments.

7 Comments

This is handy for simple needs but the alpha range is only a-f, so the security/complexity of the generated string isn't as high as it could be.
Better to use base64, which is also built in: SecureRandom.base64(16).gsub(/=+$/,'')
Not an issue for an API key, but there's also the handy urlsafe_base64 method: SecureRandom.urlsafe_base64(16) => "XpMnLfc3FySd-C4V2Ipxag"
Why is it better to use base64
Even better SecureRandom.urlsafe_base64(length)
|
28

All letters and digits, that's how numbers are represented in base 36.

api_string = Array.new(32){rand(36).to_s(36)}.join

Comments

15

8.times.map { [*'0'..'9', *'a'..'z'].sample }.join

3 Comments

'0'..'9' generates an array from 0 to 9, and 'a'..'z' generates an array from a to z, but what exactly does the * before each of them does?
'0'..'9' is range and * is splat operator. It splits the elements of the range into single items which are returned as a group, so basically * is helping you to separate out elements so that they can be sampled out using sample method
have a look at this answer: stackoverflow.com/a/72738840/7365329
4

Newer versions of Ruby support SecureRandom.base58, which will get you much denser tokens than hex, without any special characters.

> SecureRandom.base58(24)
> "Zp9N4aYvQfz3E6CmEzkadoa2" 

1 Comment

This answer it's much way better than the accepted one.
2

Here's one way to do it:

POSSIBLE = (('A'..'Z').to_a + (0..9).to_a)
api_string = (0...32).map { |n| POSSIBLE.sample }.join

If you have Active Support available you can also do this to make an API-key-like string:

ActiveSupport::SecureRandom.hex(32)

Comments

2

i forgot from where, but i've read this somehow this morning

l,m = 24,36
rand(m**l).to_s(m).rjust(l,'0')

it create random number from 0 to power(36,24), then convert it to base-36 string (that is 0-9 and a-z)

2 Comments

Except it's not always true that rand(36**len).to_s(36).length == len, so you will have to do rand(36**len).to_s(36).rjust(len, '0')
1
CHARS = (?0..?9).to_a + (?a..?z).to_a
api_string = 32.times.inject("") {|s, i| s << CHARS[rand(CHARS.size)]}

Comments

1
((('a'..'z').to_a + (0..9).to_a)*3).shuffle[0,(rand(100).to_i)].join

Replace rand(100) with rand(n) where n is the maximum length of your desired string.

Comments

1

This will generate a lower random string from 32 to 50 characters including numbers and letters, both:

require 'string_pattern'

puts "32-50:/xN/".gen

Comments

0

using SecureRandom of ruby language.

require 'securerandom' randomstring = SecureRandom.hex(5)

It will generate the n*2 random string contains “0-9″ and “a-f”

Comments

0

you can use Time in miliseconds with redix base 36

Example: Time.now.to_f.to_s.gsub('.', '').ljust(17, '0').to_i.to_s(36) # => "4j26l5vq964"

have a look at this answer to better explaination: https://stackoverflow.com/a/72738840/7365329

Comments

-1
Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond).to_s(36)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.