安全的随机生成十六进制数字

8
尝试使用Rails的SecureRandom类生成随机数字。我们可以使用SecureRandom.hex创建一个只包含数字而没有字母的随机数吗?
例如:
不是:
SecureRandom.hex(4)
=> "95bf7267"

它应该提供

SecureRandom.hex(4)
=> "95237267"
4个回答

10

请查看SecureRandom的API文档:http://rails.rubyonrails.org/classes/ActiveSupport/SecureRandom.html

我认为你正在寻找另一种方法:#random_number。

SecureRandom.random_number(a_big_number)

因为 #hex 返回一个十六进制数,所以要求返回仅包含数字字符的随机结果是不寻常的。

对于基本用途,使用 #rand 就足够简单了。

rand(9999)

编辑:

我不知道有一个库可以生成指定长度的随机数,但似乎很容易编写一个。这是我的实现:

def rand_by_length(length)
  rand((9.to_s * length).to_i).to_s.center(length, rand(9).to_s).to_i
end

方法#rand_by_length接受一个整数作为参数,表示长度,并尝试基于该长度生成最大数字的随机数。使用String#center填充缺少的数字与随机数字字符。在指定长度的每个数字中最坏的情况下调用#rand。这可能满足您的需求。


感谢您纠正"十六进制数"的术语。我想进一步解释一下,我实际上正在寻找一个特定长度(假设为8)的随机数,而十六进制确实限制了长度,因此我想寻找类似的东西,SecureRandom可能会生成仅数字的号码。SecureRandom.random_number(n)可能不允许这样? - swapab
根据您的评论更新了我的答案。 - rossta

1
数字ID很好,因为它们更容易在电话中阅读(无需C代表查理)。
试试这个。
length = 20
id = (SecureRandom.random_number * (10**length)).round.to_s # => "98075825200269950976"

并且为了加分,将其分解以便更容易阅读

id.split(//).each_slice(4).to_a.map(&:join).join('-') # => "9807-5825-2002-6995-0976"

0

这将创建一个指定长度的数字。

length = 11

rand(10**length..(10**length+1)-1).to_s

-1
length = 4

[*'0'..'9'].sample(length).join

就是这么简单 :)


我的一分钱意见:没有星号 (0..9).to_a.sample(length).join - swapab
@swap.nil 为什么更好? - avital
这对于所需长度大于10的情况不起作用。此外,这将仅使用每个数字一次。 - natschz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接