开发者

Create Random Integer Based on Id in Ruby

开发者 https://www.devze.com 2023-03-23 00:48 出处:网络
I have a scenario where I need to generate 4 digit confirmation codes for individual orders.I don\'t want to just do random codes due to the off chance that two exact codes would be generated near the

I have a scenario where I need to generate 4 digit confirmation codes for individual orders. I don't want to just do random codes due to the off chance that two exact codes would be generated near the 开发者_如何学Csame time. Is there a way to use the id of each order and generate a 4 digit code from that? I know I am going to eventually have repetitive codes with this but it will be ok because they will not be generated around the same time.


Do you really need to base the code on the ID? Four digits only gives you ten thousand possible values so you could generate them all with a script and toss them in a database table. Then just pull a random one out of the database when you need it and put it back in when you're done with it.

Your code table would look like this:

  • code: The code
  • uuid: A UUID, a NULL value here indicates that this code is free.

Then, to grab a code, first generate a UUID, uuid, and do this:

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

(where ? would be your uuid) to reserve the code in a safe manner and then this:

select code
from code_table
where uuid = ?

(where ? is again your uuid) to pull the code out of the database.

Later on, someone will use the code for something and then you just:

update code_table
set uuid = null
where code = ?

(where code is the code) to release the code back into the pool.

You only have ten thousand possible codes, that's pretty small for a database even if you are using order by random().

A nice advantage of this approach is that you can easily see how many codes are free; this lets you automatically check the code pool every day/week/month/... and complain if the number of free codes fall below, say, 20% of the entire code space.

You have to track the in-use codes anyway if you want to avoid duplicates so why not manage it all in one place?


If your order id has more than 4 digits, it is theoreticly impossible without checking the generated value in a array of already generated values, you can do something like this:

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

Remember to clean up $confirmation_codes_in_use after using the code.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号