Я хочу создать уникальный идентификатор, который будет использоваться в URL-адресах для определения определенного ресурса. В принципе это то же самое, что и pastebin.com и т.д.
Идентификатор и ресурс не очень секретны, но я хочу, чтобы это было так, что вы просто не можете уменьшить id, а затем получить другой ресурс пользователей. Я думаю о CHAR(8)
, который будет выглядеть красиво в URL-адресе и по-прежнему будет достаточно большим, чтобы уменьшить вероятность догадок. Но как мне это создать? Для INT вы можете использовать auto_increment
и primary key
для обеспечения уникальности.
Но если я сделаю следующее:
CHAR(8)
в моем приложенииМне нужно обернуть 2 и 3. в атомной транзакции.
Но есть ли лучший способ? или я не должен заботиться о чеке (2.), потому что столкновение не происходит регулярно. Я использую MySql и .Net(С#), если это помогает. Возможно ли каким-то образом "зашифровать" автоматически инкрементированный int в качестве текстового идентификатора и снова расшифровать его с помощью 8 (или 10) символов.
Я прочитал Нужна меньшая альтернатива GUID для идентификатора базы данных, но все же уникальная и случайная для URL, которая была полезна, но использование GUID не поддерживается в MySql (насколько я знаю). Но комментарий к качеству метода LongToShortCode
в потоке также будет оценен.
Примечание: ресурсы не могут быть изменены, только просмотрены.
С уважением, Лассе
Думаю, я сделаю это вот так: 8-символьный текстовый идентификатор может хранить число до 64 ^ 8 = 2 ^ 48.
Затем я буду использовать два столбца:
Затем, когда я добавляю строку, я буду генерировать случайное целое число 2 ^ 16 и поместить его в новую строку. Идентификатор текста затем просто генерируется из двух комбинированных чисел. И поиск легко два - просто разделить его и простой поиск в базе данных. Смешное простое решение, которое должно устранить столкновение строк и быть достаточно случайным (2 ^ 16), чтобы уменьшить догадки.
Отзыв об этом подходе будет оценен.
MySql реализует UUID. Это похоже на идентификатор GUID с другим именем. Таким образом, этот параметр по-прежнему доступен для вас.
Если вы все еще собираетесь использовать char(8)
, вам нужно беспокоиться об уникальности вашего идентификатора, просто потому, что, если вы смотрите на обслуживаемые URL-адреса, вы можете не знать, что произошло нарушение, пока люди не начинают сообщать о проблемах.
Вы можете использовать идентификатор int, а затем зашифровать/расшифровать его перед его использованием, возможно, это не самая лучшая идея при большой нагрузке.
Легкий способ сделать это псевдоатомно:
Коллизии все равно могут произойти, но когда они это делают, это заставляет обе потоки снова попробовать, что в этом случае не проблема.
EDIT: я бы предложил взять первые несколько символов криптографического хэша или что-то для вашей функции генерации, но это не имеет большого значения.