Как создать уникальный 7-значный код для сущности?
когда пользователь добавляет новый элемент в мою систему, я хочу создать уникальный без увеличения псевдослучайный 7-значный код для этого элемента. Количество созданных элементов будет только в тысячах (
поскольку он должен быть уникальным, и никакие два элемента не будут иметь одинаковую информацию, я мог бы использовать хэш, но это должен быть код, которым они могут делиться с другими людьми - следовательно, 7 цифр.
моя первоначальная мысль заключалась в том, чтобы просто зациклить генерацию случайного номер, проверьте, что он еще не использовался,и если это было, промойте и повторите. Я думаю, что это разумное, хотя и неприятное решение, учитывая низкую вероятность столкновений.
ответы этот вопрос предложите создать список всех неиспользуемых чисел и перетасовать их. Вероятно, я мог бы сохранить такой список в базе данных, но мы говорим о 10 000 000 записей для чего-то относительно нечастого.
У кого-нибудь есть лучше способ?
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;
}
вы можете использовать incrementing ID, а затем XOR его на некотором фиксированном ключе.
const int XORCode = 12345;
private int Encode(int id)
{
return id^XORCode;
}
private int Decode(int code)
{
return code^XORCode;
}
честно говоря, если вы хотите генерировать только пару тысяч 7-значных кодов, в то время как 10 миллионов различных кодов будут доступны, я думаю, что достаточно просто генерировать случайный и проверять столкновение.
вероятность столкновения при первом попадании будет, в худшем случае, около 1 из тысячи, и вычислительные усилия, чтобы просто сгенерировать новый 7-значный код и снова проверить столкновение, будут намного меньше, чем сохранение словаря или аналогичного решения.
использование GUID вместо 7-значного кода, как предложил harryovers также, безусловно, будет работать, но, конечно, GUID будет немного сложнее запомнить для ваших пользователей.
Я бы предложил использовать guid вместо 7-значного кода, поскольку он будет более уникальным, и вам не нужно беспокоиться о их создании, поскольку .NET сделает это за вас.
все решения для "уникального" идентификатора должны иметь где-то базу данных: либо ту, которая содержит используемые идентификаторы, либо ту, которая содержит свободные идентификаторы. Как вы заметили, база данных с бесплатными идентификаторами будет довольно большой, поэтому чаще всего люди используют базу данных "used IDs" и проверяют коллизии.
тем не менее, некоторые базы данных предлагают генератор/последовательность "random ID", который уже возвращает идентификаторы в диапазоне в случайном порядке.
Это работает с помощью генератора случайных чисел, который может создать все числа в диапазоне, не повторяясь плюс функция, которую вы можете сохранить это состояние где-то. Итак, вы запускаете генератор один раз, используете ID и сохраняете новое состояние. Для следующего запуска вы загружаете состояние и сбрасываете генератор до последнего состояния, чтобы получить следующий случайный идентификатор.
Я предполагаю, что у вас будет таблица созданный те. В этом случае я не вижу проблем с выбором случайных чисел и проверкой их по базе данных, но я бы не стал делать это индивидуально. Создание их дешево, выполнение запроса БД дорого по сравнению с этим. Я бы генерировал 100 или 1000 за раз, а затем спрашивал БД, какой из них существует. Держу пари, вам не придется делать это дважды большую часть времени.
У вас есть
Если вы объедините уникальный порядковый номер из 4 цифр со случайным числом из 3 цифр, вы будете уникальными и случайными. Вы увеличиваете порядковый номер с каждым новым идентификатором, который вы создаете.
вы можете просто добавить их в любом порядке или смешать их.
seq = abcd, rnd = ABC
вы можете создать следующие идентификаторы:
- abcdABC
- ABCabcd
- aAbBcCd
Если вы используете только один алгоритм смешивания, у вас будут уникальные номера, которые выглядят случайными.
Я бы попытался использовать LFSR (линейный регистр сдвига обратной связи) код действительно прост, вы можете найти примеры везде ie Википедия и хотя он не криптографически защищен, он выглядит очень случайным. Также реализация будет очень быстрой, так как она использует в основном операции сдвига.
только с тысячами элементов в базе данных ваша оригинальная идея кажется разумной. Проверка существования значения в отсортированном (индексированном) списке из нескольких десятков тысяч элементов потребует только нескольких выборок данных и сравнений.
предварительная генерация списка не кажется хорошей идеей, потому что вы либо сохраните больше чисел, чем необходимо, либо вам придется иметь дело с их исчерпанием.
вероятность попадания очень низкая.
Например, у вас есть 10^4 пользователей и 10^7 возможных идентификаторов.
Вероятность того, что вы выберете used ID 10 раз подряд, теперь составляет 10^-30.
Этот шанс меньше, чем один раз в жизни любого человека.
Ну, ты может попросите пользователя выбрать свой собственный 7-значный номер и проверить его по совокупности существующих номеров (которые вы бы сохранили, поскольку они были использованы), но я подозреваю, что вы будете фильтровать много ответов типа 1234567, 7654321, 9999999, 7777777 и, возможно, потребуется несколько регулярных выражений для достижения фильтрации, плюс вам придется предупредить пользователя о таких последовательностях, чтобы не иметь плохого, повторяющегося пользовательского ввода.