Создать случайное целое число на основе идентификатора в Ruby - PullRequest
0 голосов
/ 26 июля 2011

У меня есть сценарий, в котором мне нужно генерировать 4-значные коды подтверждения для отдельных заказов.Я не хочу просто делать случайные коды из-за вероятности того, что два точных кода будут сгенерированы в одно и то же время.Есть ли способ использовать идентификатор каждого заказа и генерировать 4-значный код из этого?Я знаю, что со временем у меня будут повторяющиеся коды, но все будет в порядке, потому что они не будут генерироваться в одно и то же время.

Ответы [ 2 ]

2 голосов
/ 26 июля 2011

Вам действительно нужно основывать код на идентификаторе?Только четыре цифры дают вам десять тысяч возможных значений, чтобы вы могли сгенерировать их все с помощью скрипта и поместить их в таблицу базы данных.Затем просто извлеките случайную единицу из базы данных, когда она вам понадобится, и вставьте ее обратно, когда закончите.

Ваша кодовая таблица будет выглядеть так:

  • 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% от всего пространства кода.

Вы должны отслеживатьвсе равно используются коды, если вы хотите избежать дублирования, так почему бы не управлять всем этим в одном месте?

0 голосов
/ 26 июля 2011

Если ваш идентификатор заказа имеет более 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 после использования кода.

...