SecureRandom会生成一个唯一的字符串还是我必须检查?

时间:2015-06-17 10:20:10

标签: ruby-on-rails ruby

我将每个已创建项目的唯一代码归因于在URL中使用。我在模型中创建项目时执行此操作:

class Item < ActiveRecord::Base
  before_create { self.code = SecureRandom.urlsafe_base64 }
end

但我不知道生成的代码是否真的是唯一的。我是否必须在创建期间检查唯一性,但如果Items表增长,这可能会花费不必要的时间和资源:

before_create :generate_unique_code

def generate_unique_code
  loop do
    code = SecureRandom.urlsafe_base64
    unless Item.where(:code => code).any?
      self.code = code
      break
    end
  end
end

我可以相信SecureRandom.urlsafe_base64的唯一性并跳过检查吗?

3 个答案:

答案 0 :(得分:1)

计算机生成的字符串中没有任何内容是完全随机的。从技术上讲,两个字符串可能相同的可能性非常低。

在高度并发的系统中更是如此。如果情况并非如此,那么您可以做的只是在数据库级别添加唯一约束(也称为唯一索引)。这样,在两个字符串相等的远程事件中,数据库将拒绝第二个字符串。

如果你需要将它用于查询,你可能会在该字段上有一个索引,因此它不应该添加任何不合理的开销。

作为旁注,SecureRandom Ruby 库,而不是Rails库。

答案 1 :(得分:1)

为了使它具有唯一性,它必须(i)遵循一条规则,使其永远不会命中先前生成的输出(例如通过在调用它时调用一对一函数,它只能在单个线程下工作,这使得它是非随机的,或者(ii)保留某个地方所有先前生成的输出的记录,但不是这种情况,这也使得它是非随机的。在任何一种情况下,你都应该能够说出它不是唯一的。

然而,数学和工程学是不同的。即使它不是唯一的,您也可以将其视为事实上的独特之处。这就是程序员所做的。

答案 2 :(得分:0)

Rails master分支包含一个与此相关的新模块。 https://github.com/rails/rails/blob/master/activerecord/lib/active_record/secure_token.rb

您可以参考的其他解决方案。

Generating unique token on the fly with Rails