Создание генератора случайных чисел в jscript и предотвращение дубликатов

#javascript

#javascript

Вопрос:

Мы пытаемся создать генератор случайных чисел для создания серийных номеров для продуктов на виртуальной сборочной линии. Мы получили случайные числа для генерации, однако, поскольку это серийные номера, мы не хотим, чтобы он создавал дубликаты. Есть ли способ, которым он может вернуться и проверить, было ли сгенерированное число уже сгенерировано, а затем сообщить ему, что если это дубликат, сгенерировать новый номер и повторять этот процесс до тех пор, пока у него не будет «уникального» номера.

Комментарии:

1. Не проще ли было бы хэшировать имя / идентификатор / что-то-характерное для каждого продукта?

2. @JCOC611 — хэши будут сталкиваться, поэтому они не те, что вы хотите использовать здесь. Детерминированный алгоритм с гарантированной уникальностью — это то, что вам нужно.

Ответ №1:

Смысл серийных номеров в том, что они НЕ являются случайными. Последовательный, по определению, означает, что что-то расположено последовательно. Почему бы просто не использовать увеличивающееся число?

Ответ №2:

Самый простой способ исправить эту проблему — избежать ее. Используйте что-то, что монотонно увеличивается (например, время), чтобы сформировать часть вашего серийного номера. К этому вы можете добавить некоторое фиксированное значение, которое идентифицирует строку или что-то еще.

Таким образом, ваш формат серийного номера может быть NNNNYYYYMMDDHHMMSS, где NNNN — 4-значный номер строки, ГГГГ — 4-значный год, ММ — 2-значный месяц, …

Если вы можете создавать несколько элементов в секунду в строке, то добавляйте компоненты даты, пока не дойдете до точки, где возможен только один элемент в единицу времени — или просто добавьте количество элементов, созданных за этот день, в компонент YYYYMMDD (например, NNNYYYYYMDDCCCCCC).

Комментарии:

1. Вы можете сократить его, используя более высокое основание для некоторых чисел, скажем, основание-32, используя числа 0-9A-Z (минус ILOQ). Это позволит вам кодировать год в 3 «цифрах», месяц и день каждый в 1 «цифре».

Ответ №3:

С действительно случайным числом вам пришлось бы хранить всю коллекцию и просматривать ее для каждого числа. Очевидно, это означало бы, что ваша генерация будет становиться все медленнее и медленнее по мере увеличения количества генерируемых вами ключей (поскольку для этого пришлось бы повторять попытки все чаще и сравнивать с большим набором данных).

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

Уникальные идентификаторы НИКОГДА НЕ бывают случайными — GUID и тому подобное основаны на системном времени и (чаще всего) MAC-адресе. Они глобально уникальны из-за используемого алгоритма и особенностей компьютера, а не из-за размера значения или какого-либо уровня случайности.

Лично я бы сделал все возможное, чтобы либо использовать последовательное значение (возможно, с уникальным префиксом, если у вас несколько каналов), либо, что лучше, использовать реальный GUID для ваших целей.

Ответ №4:

это то, что вы ищете?

 var rArray;

function fillArray (range)
{
    rArray = new Array ();

    for(var x = 0; x < range; x  )
    rArray [x] = x;
}

function randomND (range)
{
    if (rArray == null || rArray.length < 1)
    fillArray (range);

    var pos = Math.floor(Math.random()*rArray.length);
    var ran = rArray [pos];

    for(var x = pos; x < rArray.length; x  )
    rArray [x] = rArray [x 1]; 

    var tempArray = new Array (rArray.length-1)
    for(var x = 0; x < tempArray.length; x  )
    tempArray [x] = rArray [x];

    rArray = tempArray;

    return ran;
}