为了创建非连续的唯一用户ID,我知道我可以使用:
SecureRandom.uuid
问题在于它有点慢,我们对API的响应能力很着迷。我试图确定我是否可以用这样的东西替换id代:
rand(36**10).to_s(36)
更快,并生成一个看似随机的,通常为10位的字母数字。这样安全吗? rand
36^10 ~ 3.5e15
会在{{1}}大的可能性范围内真正生成或多或少均匀分布的ID吗?或者在实践中,分布是不均匀的,因此更容易产生碰撞?
我应该考虑的任何其他问题或我应该考虑的替代方案?
答案 0 :(得分:2)
这是一个有点偏离主题,因为你询问了random
方法的安全性,但无论如何:
您提到需要随机数来生成碰撞概率较低的user_ids。我认为讨论性能问题是不值得的:
require 'benchmark'
require 'securerandom'
n = 100_000
Benchmark.bmbm(15) do |x|
x.report("random:") { n.times do; rand(36**10).to_s(36); end }
x.report("uuid:") { n.times do; SecureRandom.uuid; end }
x.report("hex:") { n.times do; SecureRandom.hex; end }
end
# Rehearsal ---------------------------------------------------
# random: 0.070000 0.010000 0.080000 ( 0.062774)
# uuid: 0.800000 0.000000 0.800000 ( 0.802512)
# hex: 0.360000 0.000000 0.360000 ( 0.361002)
# ------------------------------------------ total: 1.240000sec
#
# user system total real
# random: 0.060000 0.000000 0.060000 ( 0.062458)
# uuid: 0.820000 0.000000 0.820000 ( 0.820784)
# hex: 0.340000 0.000000 0.340000 ( 0.341963)
你是对的SecureRandom.uuid
比random
慢13倍。但是你仍然可以每毫秒生成~1000 uuids。这在数据库中存储这样的uuid所需的时间可以忽略不计。 IMO对数据库的更新至少需要2-3ms。
此外,SecureRandom.uuid
的可读性远远优于rand(36**10).to_s(36)
。
答案 1 :(得分:1)
也许你可以将缓慢的过程移到后台: