Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating random number of length 6 with SecureRandom in Ruby

I tried SecureRandom.random_number(9**6) but it sometimes returns 5 and sometimes 6 numbers. I'd want it to be a length of 6 consistently. I would also prefer it in the format like SecureRandom.random_number(9**6) without using syntax like 6.times.map so that it's easier to be stubbed in my controller test.

like image 919
gogofan Avatar asked Dec 08 '22 18:12

gogofan


2 Answers

You can do it with math:

(SecureRandom.random_number(9e5) + 1e5).to_i

Then verify:

100000.times.map do
  (SecureRandom.random_number(9e5) + 1e5).to_i
end.map { |v| v.to_s.length }.uniq
# => [6]

This produces values in the range 100000..999999:

10000000.times.map do
  (SecureRandom.random_number(9e5) + 1e5).to_i
end.minmax
# => [100000, 999999]

If you need this in a more concise format, just roll it into a method:

def six_digit_rand
  (SecureRandom.random_number(9e5) + 1e5).to_i
end
like image 85
tadman Avatar answered Dec 11 '22 10:12

tadman


To generate a random, 6-digit string:

# This generates a 6-digit string, where the
# minimum possible value is "000000", and the
# maximum possible value is "999999"
SecureRandom.random_number(10**6).to_s.rjust(6, '0')

Here's more detail of what's happening, shown by breaking the single line into multiple lines with explaining variables:

  # Calculate the upper bound for the random number generator
  # upper_bound = 1,000,000
  upper_bound = 10**6

  # n will be an integer with a minimum possible value of 0,
  # and a maximum possible value of 999,999
  n = SecureRandom.random_number(upper_bound)

  # Convert the integer n to a string
  # unpadded_str will be "0" if n == 0
  # unpadded_str will be "999999" if n == 999999
  unpadded_str = n.to_s

  # Pad the string with leading zeroes if it is less than
  # 6 digits long.
  # "0" would be padded to "000000"
  # "123" would be padded to "000123"
  # "999999" would not be padded, and remains unchanged as "999999"
  padded_str = unpadded_str.rjust(6, '0')
like image 42
Eliot Sykes Avatar answered Dec 11 '22 09:12

Eliot Sykes