Как создать уникальный 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 и, возможно, потребуется несколько регулярных выражений для достижения фильтрации, плюс вам придется предупредить пользователя о таких последовательностях, чтобы не иметь плохого, повторяющегося пользовательского ввода.