Генерация уникального ссылочного номера стратегии - PullRequest
6 голосов
/ 10 декабря 2008

Хм ... вот где мое знание CS подводит меня. Я хочу написать алгоритм, который генерирует уникальный ссылочный номер.

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

В идеале я не хочу запрашивать свой уровень персистентности, чтобы узнать, использовался ли ранее реф.

Какие стратегии я могу использовать?

Ответы [ 7 ]

2 голосов
/ 10 декабря 2008

Если на это число когда-нибудь будут ссылаться люди, я призываю вас следовать этим рекомендациям в своем решении:

Каков наилучший формат для номера клиента, номера заказа?

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

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

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

2 голосов
/ 10 декабря 2008

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

1 голос
/ 10 декабря 2008

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

Используйте GUID, но закодируйте его base64 выглядит как 7QDBkvCA1 + B9K / U0vrQx1A, который составляет 22 байта, который все еще длиннее, чем собственный Guid ... но короче, чем типичное строковое представление.

См. Текстовое кодирование здесь: http://en.wikipedia.org/wiki/Globally_Unique_Identifier

Другим вариантом будет хэширование Guid, но вы потеряете часть уникальности, так каков ваш уровень допуска для неуникальных предметов?

==========

Если у вас есть один процесс, вставляющий в таблицу, вы можете использовать алгоритм HiLo и быть уверенным, что вам не нужно каждый раз обращаться к БД. Вы просто сохраните в памяти последнее старшее значение ... когда вы запустите процесс, вы попадете в базу данных, чтобы узнать, где вы остановились: Что такое алгоритм Hi / Lo?

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

0 голосов
/ 11 декабря 2008

Я успешно делал это в производственной системе:

  • Взять текущее время (UTC, с точностью до микросекунды)
  • Ваш идентификатор процесса, идентификатор потока
  • Имя вашего компьютера
  • Значение соли (в основном просто строка, уникальная для вашей программы)
  • случайное значение (предпочтительно криптографический PRNG)

Поместите это в память, либо в виде строки, либо XOR значений вместе или что-то подобное. Тогда:

  • Хэш, например, SHA-1
  • Сделайте мод N на полученном числе, чтобы уменьшить вывод до N байтов
  • Преобразование в шестнадцатеричное или что-то печатное, если вам это нужно.

Просто помните, что сокращение UID до N байтов увеличит шансы на UID-столкновения.

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

0 голосов
/ 11 декабря 2008

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

т.е. microtime () + ранд (10000,99999)

0 голосов
/ 11 декабря 2008

Одним из способов может быть генерирование чисел на основе меньшего подмножества чисел. Например, вы можете использовать двоичную последовательность для генерации на основе нумерации Годеля. Например, отображение 000 на 111 на 5z, 3y, 2x дает 0, 2, 3, 6, 5, 10, 15, 30.

Конечно, это слишком упрощенно. Но, перебирая «соленые» числа для генерации ссылочных номеров, вам не нужно было бы вообще отслеживать ссылочные номера. При условии или, конечно, вы были достаточно уверены, что вам не нужно учитывать столкновения.

0 голосов
/ 10 декабря 2008

Обрежьте GUID до нужного вам размера.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...