在Ruby中基于Id创建随机整数

时间:2011-07-26 00:01:03

标签: ruby random saltedhash

我有一个场景,我需要为个别订单生成4位数的确认码。我不想只做随机码,因为在同一时间附近会产生两个确切的代码。有没有办法使用每个订单的ID并从中生成一个4位数的代码?我知道我最终会有重复的代码,但它会没问题,因为它们不会在同一时间生成。

2 个答案:

答案 0 :(得分:2)

您真的需要将代码基于ID吗?四位数只能为您提供一万个可能的值,因此您可以使用脚本生成它们并将它们放在数据库表中。然后在需要时从数据库中随机抽出一个,并在完成后将其重新放入。

您的代码表如下所示:

  • code:代码
  • uuid:UUID,此处的NULL值表示此代码是免费的。

然后,要获取代码,首先生成UUID uuid,然后执行此操作:

update code_table
set uuid = ?
where code = (
    select code
    from code_table
    where uuid is null
    order by random()
    limit 1
)
-- Depending on how your database handles transactions
-- you might want to add "and uuid is null" to the outer
-- WHERE clause and loop until it works

?将是您的uuid)以安全的方式保留代码然后:

select code
from code_table
where uuid = ?

(其中?再次是你的uuid)将代码从数据库中拉出来。

稍后,有人会将代码用于某些事情,然后你就是:

update code_table
set uuid = null
where code = ?

(其中code是代码)将代码释放回池中。

您只有一万个可能的代码,即使您使用order by random(),这对于数据库来说也相当小。

这种方法的一个很好的优点是你可以很容易地看到有多少代码是免费的;这使您可以每天/每周/每月/自动检查代码池...并且如果免费代码的数量低于整个代码空间的20%,则会抱怨。

如果你想避免重复,你必须跟踪使用中的代码,为什么不在一个地方管理它?

答案 1 :(得分:0)

如果您的订单ID超过4位,理论上如果不检查已生成值的数组中的生成值,您可以执行以下操作:

require 'mutex'
$confirmation_code_mutex = Mutex.new
$confirmation_codes_in_use = []

def generate_confirmation_code
  $confirmation_code_mutex.synchronize do
    nil while $confirmation_codes_in_use.include?(code = rand(8999) + 1000)
    $confirmation_codes_in_use << code
    return code
  end
end

请务必在使用代码后清理$confirmation_codes_in_use