Уникальный код в стиле Tinyurl: потенциальный алгоритм предотвращения столкновений - PullRequest
7 голосов
/ 11 августа 2009

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

  • Я использую систему base-20 (без заглавных букв, цифр, гласных или l, чтобы избежать путаницы и непослушных слов)
    • База-20 допускает 64 миллиона комбинаций
  • Я буду вставлять потенциально 5-10 тысяч записей одновременно, поэтому в теории я бы использовал массовые вставки, что означает, что использование уникального ключа, вероятно, не будет эффективным или привлекательным (особенно если будет много коллизий ) * +1010 *
  • Не исключено, что можно заполнить 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 миллионов, сработал бы, но я слишком туп, чтобы знать, возможно ли это.

Ответы [ 6 ]

8 голосов
/ 11 августа 2009

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

1 голос
/ 11 августа 2009

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

1 голос
/ 11 августа 2009

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

0 голосов
/ 11 августа 2009

@ Ник Льюис:

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

0 голосов
/ 11 августа 2009

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

0 голосов
/ 11 августа 2009

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

...