Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用rand生成uuid是否不安全?_Ruby - Fatal编程技术网

Ruby 使用rand生成uuid是否不安全?

Ruby 使用rand生成uuid是否不安全?,ruby,Ruby,要创建非连续、唯一的用户id,我知道我可以使用: SecureRandom.uuid 问题是它有点慢,我们被API的响应能力所困扰。我正在尝试确定是否可以用以下内容替换id生成: rand(36**10).to_s(36) 这是更快的,并生成一个看似随机的,通常是10位字母数字。这安全吗?rand真的会在36^10~3.5e15巨大的可能性空间中生成或多或少均匀分布的id吗?或者在实践中,分布是否会不均匀,从而更有可能产生碰撞 P>我应该知道的或者其他的选择我应该考虑? < P>也许你可以

要创建非连续、唯一的用户id,我知道我可以使用:

SecureRandom.uuid
问题是它有点慢,我们被API的响应能力所困扰。我正在尝试确定是否可以用以下内容替换id生成:

rand(36**10).to_s(36)
这是更快的,并生成一个看似随机的,通常是10位字母数字。这安全吗?
rand
真的会在
36^10~3.5e15
巨大的可能性空间中生成或多或少均匀分布的id吗?或者在实践中,分布是否会不均匀,从而更有可能产生碰撞


<> P>我应该知道的或者其他的选择我应该考虑?

< P>也许你可以把这个缓慢的过程移到背景:

  • 在快速数据存储(例如Redis)中保留UUID池
  • 当API需要uuid时,获取最旧的uuid并将其从池中删除
  • 有一个后台作业,用于监视池,并在大小降至限制以下时添加新的uuid

这有点离题,因为您询问了
随机方法的安全性,但无论如何:

您提到,您需要随机数来生成碰撞概率较低的用户ID。我认为不值得讨论性能问题:

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个UUID。这对于在数据库中存储这样一个uuid所需的时间来说是微不足道的。IMO数据库更新至少需要2-3毫秒


此外,
SecureRandom.uuid
的可读性比您的
rand(36**10)要好得多。谢谢。这是个好主意,它会解决我的问题。然而,如果
rand
代码实际上是相当安全的,我更喜欢这种解决方案,因为它更简单。没错,它更复杂,但我认为它远没有证明随机数生成器是安全的那么难。是的,但请记住,我没有用它来加密信用卡或类似的东西。我只需要创建唯一的用户ID,其冲突概率非常低,并且相当难以猜测。认为调用Redis这样的外部服务比简单的
SecureRandom.uuid
更快是荒谬的
Benchmark.measure{100000.times{SecureRandom.uuid}}。总计
在我的旧MacBook上返回0.78秒以下。这意味着每毫秒约1000个uuid。我从未使用过SecureRandom,所以我不知道它有多快。OP似乎认为它很慢。我并不是说它会更快,只是展示了一种使API更具响应性的技术。还有一个工具箱工具。哇,奇怪,当我在IRB中运行它时,会有一秒钟的停顿来生成一个one@Jonah这很奇怪;您可能需要提供其他详细信息。我无法在任何系统上重现这种行为。好的,所以在第一次呼叫时,它似乎只有1-2秒的延迟。我启动irb,然后执行
要求的'securerandom'
,然后执行
securerandom.uuid
--暂停1-2秒,然后执行结果。然后,如果我再调用
SecureRandom.uuid
,它会立即返回。@Jonah也无法重现,但还行。您是否确实确定(a)您有性能瓶颈,以及(b)您的数据库还不能生成uuid?(a)请参阅我对@spickermann的回复。(b) 我不知道答案是什么,我现在正在使用redis,但计划在生产中切换到postgres,或者其他东西。(a)请参阅我对您答复的答复,(b)postgres有UUID;我个人认为不使用SecureRandom的UUID没有多大价值。