Уникальный код в стиле Tinyurl: потенциальный алгоритм предотвращения коллизий

У меня есть система, которая требует уникального 6-значного кода для представления объекта, и я пытаюсь придумать хороший алгоритм для их создания. Вот предварительные требования:

  • I'm using a base-20 system (no caps, numbers, vowels, or l to prevent confusion and naughty words)
    • The base-20 allows 64 million combinations
  • Я буду вставлять потенциально 5-10 тысяч записей за один раз, поэтому теоретически я бы использовал массовые вставки, что означает, что использование уникального ключа, вероятно, не будет эффективным или красивым (особенно, если начинается много коллизий)
  • Не исключено заполнение 10% комбинаций, поэтому существует высокий потенциал для множества коллизий.
  • Я хочу убедиться, что коды не последовательные

У меня была идея, которая звучала так, как будто она сработает, но я недостаточно разбираюсь в математике, чтобы понять, как ее реализовать: если я начну с 0 и увеличу на N, а затем конвертирую в base-20, кажется, что должен быть некоторым значением для N, которое позволяет мне подсчитывать каждое значение от 0 до 63 999 999 перед повторением любого.

Например, переход от 0 до 9 с использованием N = 3 (то есть 10 по модулю 3): 0, 3, 6, 9, 2, 5, 8, 1, 4, 7.

Есть ли какой-нибудь волшебный математический метод для определения значений N для некоторого большего числа, который может считать через весь диапазон без повторения? В идеале число, которое я выбираю, должно было бы как бы прыгать по множеству, так что было бы неочевидно, что существует шаблон, но я не уверен, насколько это возможно.

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


person Dan Breen    schedule 10.08.2009    source источник
comment
Простые числа ... Думаю, я действительно плохо разбираюсь в математике; это кажется очевидным на заднем плане. Спасибо всем, кто ответил. Я отдал должное фантомбрену, который ответил первым.   -  person Dan Breen    schedule 11.08.2009
comment
Поскольку вы упомянули tinyurl, мой ответ на этот вопрос может быть применим: stackoverflow.com/questions/1051949/   -  person FogleBird    schedule 11.08.2009
comment
Не забудьте удвоить коды, чтобы они не шли подряд.   -  person Beta    schedule 11.08.2009
comment
возможный дубликат Создание собственного uid стиля Tinyurl   -  person user    schedule 04.07.2013


Ответы (6)


Все, что вам нужно, это число, которое не имеет делителей с вашим ключевым пространством. Самый простой вариант - использовать простое число. Вы можете найти в Google большие простые числа или использовать http://primes.utm.edu/lists/small/10000.txt

person Cullen Walsh    schedule 10.08.2009

Любое простое число, которое не является фактором длины последовательности, должно иметь возможность охватывать последовательность без повторения. Для 64000000 это означает, что вам не следует использовать 2 или 5. Конечно, если вы не хотите, чтобы они генерировались последовательно, генерация их на 2 или 5, вероятно, также не очень хорошо. Мне лично нравится номер 73973!

person Nick Lewis    schedule 10.08.2009

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

person Andrew Y    schedule 11.08.2009

Моя математика немного ржавая, но я думаю, вам просто нужно убедиться, что GCF N и 64 миллиона равны 1. Я бы на всякий случай выбрал простое число (которое не делится равномерно на 64 миллиона).

person Jonathan Rupp    schedule 10.08.2009

@ Ник Льюис:

Ну, только если простое число не делит 64 миллиона. Таким образом, для задающего вопросы числа вроде 2 или 5, вероятно, не подходят.

person quanticle    schedule 10.08.2009

Не изобретайте велосипед: http://en.wikipedia.org/wiki/Universally_Unique_Identifier

person Pyrolistical    schedule 10.08.2009
comment
UUID не может быть шестизначным кодом из двадцати символов алфавита. - person Karl; 11.08.2009