例如:如果我在Rails中创建新用户,则ID号将为1,2,3等等。在URL中,用户ID将类似于" users / 1"。我的问题是:如何为每个新用户创建一个随机数?所以id不会是1,2,3等等。更像是id:643893,姓名:Carl,年龄:34岁?
答案 0 :(得分:3)
如果你真的坚持数字,你可以做这样的事情
def random_id
Random.new.bytes(8).bytes.join[0,8]
end
5.times { puts random_id }
输出
19854517
11802301
16391219
18414719
35583913
无论如何,我相信你有一点XY Problem,你的最终目标是为你的用户生成唯一的ID。上面的函数是随机的,但没有检查你的数据库,你不知道结果是否是唯一的。以下是我采取的一些替代方法:
如果您愿意,它不是8 数字,但您可以切片uuid
require "securerandom"
SecureRandom.uuid.split("-").first
# b05582d8
那就是说,我认为使用整个事情要好得多
SecureRandom.uuid
# b05582d8-3489-4bba-b94f-565ee458b1f9
答案 1 :(得分:1)
由于您要求用户ID,我将假设
因此,您不需要纯粹的随机ID,否则您最终会因the birthday problem而导致碰撞。在仅仅10 ^ 8个随机用户ID中,这意味着在大约10 ^ 4个用户之后发生冲突的可能性很大,并且总是可能在此之前发生。
您正在寻找的是排列功能。使用一些基本数论,这是一种简单,非安全的方法:
N = 99999999 # set of ordered numbers to permute = {0,1,2,...,N-1}
P = 1000000007 # prime number larger than N
A = 181932213 # random integer: 2 <= A < P
B = 611232645 # random integer: 0 <= B < P
def get_user_id( i )
j = i.instance_of?(Fixnum) ? i : i.dup # i.dup if i is a Bignum
j -= 1
begin j = ( A * j + B ).modulo P end until j < N
j + 1
end
在内部,您仍然希望生成增量ID id
。然后get_user_id(id)
返回一个8位数字(或更少),您可以将其用作user_id
,保证与所有非零8-的任何其他user_id
不冲突数字id
。
举例说明:
1.upto(N) do |i|
j = get_user_id(i)
puts "#{i}\t#{j}"
end
输出:
1 41168842
2 45894710
3 11122313
4 74043578
5 78434518
6 72415977
...
请注意,任何知道/怀疑您正在使用此算法的人都可以非常轻松地确定N,P,A和B来自获取某些连续生成的值,并获取您想要的基础id
值保持隐藏。如果你需要比这更安全的东西,那么考虑研究一下排列密码。
答案 2 :(得分:0)
下面是以字母表开头的示例。
def self.generate_reg_no
@reg_no = PatientReg.last
@reg_no.blank? ? (@reg_no = 'REG00') : (@reg_no = @reg_no.reg_no)
new_id =""
n = @reg_no.length
last_count = @reg_no.slice!(4..n)
new_id << "REG0" << (last_count.to_i+1).to_s
end
您可以根据自己的要求进行修改。