Как я могу создать уникальный 7-разрядный код для объекта?

Когда пользователь добавляет новый объект в моей системе, я хочу произвести уникальный не увеличивающий псевдослучайный 7-разрядный код для того объекта. Количество созданных объектов только пронумерует в тысячах (<10,000).

Поскольку это должно быть уникально, и никакие два объекта не будут иметь ту же информацию, я мог использовать хеш, но это должен быть код, который они могут совместно использовать с другими людьми - следовательно эти 7 цифр.

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

Ответы на этот вопрос предлагают генерировать список всех неиспользованных чисел и переставить их. Я мог, вероятно, сохранить список как это в базе данных, но мы говорим 10 000 000 записей для чего-то относительно нечастого.

У кого-либо есть лучший путь?

10
задан Community 23 May 2017 в 11:43
поделиться

11 ответов

Выберите 7-значное простое число A и большое простое число B и

int nth_unique_7_digit_code(int n) {
    return (n * B) % A;
}

Количество все уникальные коды, сгенерированные этим, будут иметь вид A .

Если вы хотите быть более «безопасным», выполните pow (some_prime_number, n)% A , т.е.

static int current_code = B;
int get_next_unique_code() {
   current_code = (B * current_code) % A;
   return current_code;
}
15
ответ дан 3 December 2019 в 14:34
поделиться

Честно говоря, если вам нужно сгенерировать всего пару тысяч 7-значных кодов, в то время как будет доступно 10 миллионов различных кодов, я думаю, что просто сгенерировать случайный код и проверить его на столкновение будет достаточно.

Шанс столкновения при первом ударе будет, в худшем случае, примерно 1 на тысячу, а вычислительные усилия для того, чтобы просто сгенерировать новый 7-значный код и снова проверить его на столкновение, будут гораздо меньше, чем для хранения словаря или других подобных решений.

Использование GUID вместо 7-значного кода, как предложил harryovers, тоже, конечно, будет работать, но, конечно, GUID будет немного сложнее запомнить вашим пользователям.

4
ответ дан 3 December 2019 в 14:34
поделиться

Все решения для "уникального" ID должны иметь где-то базу данных: Либо та, которая содержит использованные ID, либо та, которая содержит свободные ID. Как вы заметили, база данных со свободными идентификаторами будет довольно большой, поэтому чаще всего люди используют базу данных "использованных идентификаторов" и проверяют их на коллизии.

Тем не менее, некоторые базы данных предлагают генератор/последовательность "случайных ID", который уже возвращает ID в диапазоне в случайном порядке.

Это работает за счет использования генератора случайных чисел, который может создавать все числа в диапазоне, не повторяясь, плюс есть возможность сохранить его состояние. Итак, вы запускаете генератор один раз, используете идентификатор и сохраняете новое состояние. При следующем запуске вы загружаете это состояние и сбрасываете генератор в последнее состояние, чтобы получить следующий случайный ID.

2
ответ дан 3 December 2019 в 14:34
поделиться

Я бы посоветовал использовать guid вместо 7-значного кода, так как он будет более уникальным, и вам не нужно беспокоиться о его генерации, поскольку .NET сделает это за вас.

2
ответ дан 3 December 2019 в 14:34
поделиться

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

const int XORCode = 12345;

private int Encode(int id)
{
    return id^XORCode;
}

private int Decode(int code)
{
    return code^XORCode;
}
5
ответ дан 3 December 2019 в 14:34
поделиться

Я предполагаю, что у вас будет таблица сгенерированных чисел. В таком случае, я не вижу проблемы в том, чтобы выбрать случайные числа и проверить их по базе данных, но я бы не стал делать это по отдельности. Генерировать их дешево, а делать запрос к БД - дорого. Я бы сгенерировал 100 или 1000 за раз, а затем спросил у БД, какие из них существуют. Уверен, вам не придется делать это дважды большую часть времени.

2
ответ дан 3 December 2019 в 14:34
поделиться

Я бы попытался использовать LFSR (регистр сдвига с линейной обратной связью), код очень простой, вы можете найти примеры везде, например Википедия и хотя это и не является криптографически безопасным, оно выглядит очень случайным. Кроме того, реализация будет очень быстрой, поскольку в ней используются в основном операции сдвига.

1
ответ дан 3 December 2019 в 14:34
поделиться

1) Убедитесь, что параметр enable32BitAppOnWin64 для пула приложений "Центр администрирования SharePoint" имеет значение False, а для пула приложений "Корень веб-служб SharePoint" - значение False

2) Отредактируйте startHost.config:

bitness64 , являясь здесь волшебным словом

-121--1404565-

Можно использовать инкрементный идентификатор, а затем использовать XOR для некоторых фиксированных клавиш.

const int XORCode = 12345;

private int Encode(int id)
{
    return id^XORCode;
}

private int Decode(int code)
{
    return code^XORCode;
}
-121--3049998-

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

Предварительная генерация списка не звучит как хорошая идея, потому что вы либо будете хранить намного больше чисел, чем необходимо, либо вам придется иметь дело с исчерпанием их.

0
ответ дан 3 December 2019 в 14:34
поделиться

Вероятность получения совпадений очень мала.
Например, у вас 10 ^ 4 пользователей и 10 ^ 7 возможных идентификаторов.
Вероятность того, что вы выберете использованный идентификатор 10 раз подряд, теперь составляет 10 ^ -30.
Этот шанс меньше, чем один раз в жизни любого человека.

0
ответ дан 3 December 2019 в 14:34
поделиться

Что ж, вы могли попросить пользователя выбрать свой собственный 7-значный номер и проверить его на совокупности существующих номеров (которые вы бы сохранили, поскольку они были израсходованы), но я подозреваю, что вы будете фильтровать множество ответов типа 1234567, 7654321, 9999999, 7777777 и, возможно, потребуется несколько регулярных выражений для достижения фильтрации, плюс вам нужно будет предупредить пользователя против таких последовательностей, чтобы не иметь плохого, повторяющегося пользовательского ввода.

0
ответ дан 3 December 2019 в 14:34
поделиться

Может быть, если ваши префиксы имеют одинаковую длину, тогда вы можете сделать , где RIGHT (число) в ('123456', '234456', 'etc', 'etc')

-121--1475110-

Да и нет. Необходимо получить все репо, но при локальном слиянии оно приносит только измененные файлы. Здесь есть проход .

Важная линия:

git remote add upstream git://github.com/original/repo.git

И тогда фактическая выборка/слияние может быть выполнена следующим образом (два шага):

git fetch upstream master
git merge upstream/master

или в один шаг:

git pull upstream master

(примеры взяты из ссылки GitHub, приведенной выше)

-121--4293741-

Имеется < 10.000 предметы, поэтому для сохранения уникального номера для всех предметов требуется только 4 цифры. Так как у вас есть 7 цифр, у вас есть 3 цифры дополнительно.

Если объединить уникальный порядковый номер из 4 цифр со случайным числом из 3 цифр, вы будете уникальными и случайными. Порядковый номер увеличивается с каждым новым генерируемым идентификатором.

Вы можете просто добавить их в любом порядке или смешать.

seq = abcd, rnd = ABC

Можно создать следующие идентификаторы:

  • abcdABC
  • ABCabcd
  • aAbStartCd

Если вы используете только один алгоритм смешения, у вас будут уникальные числа, которые выглядят случайными.

2
ответ дан 3 December 2019 в 14:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: