Ruby on Rails - генерирует uuids в стиле bit.ly - PullRequest
5 голосов
/ 19 июля 2010

Я пытаюсь сгенерировать UUID с тем же стилем, что и для bit.ly, например:

http://bit.ly/aUekJP

или облачных приложений:

http://cl.ly/1hVU

которые еще меньше

как я могу это сделать? Сейчас я использую UUID gem для ruby, но я не уверен, возможно ли ограничить длину и получить что-то вроде этого. Я сейчас использую это:

UUID.generate.split("-")[0] => b9386070

Но я бы хотел иметь еще меньше и зная, что он будет уникальным.

Любая помощь будет очень признательна :)

Ответы [ 4 ]

14 голосов
/ 19 июля 2010

Вы путаете две разные вещи здесь. UUID - это универсально уникальный идентификатор. У него очень высокая вероятность быть уникальным, даже если миллионы из них были созданы по всему миру одновременно. Обычно отображается в виде 36-значной строки. Вы не можете отрубить первые 8 символов и ожидать, что они будут уникальными.

Bitly, tinyurl и др. Хранят ссылки и генерируют короткий код для представления этой ссылки. Они не восстанавливают URL-адрес из кода, который они ищут в хранилище данных, и возвращают соответствующий URL-адрес. Это не UUIDS.

Не зная вашего приложения, трудно посоветовать, какой метод следует использовать, однако вы можете сохранить все, на что вы указываете, в хранилище данных с помощью числового ключа, а затем перебазировать ключ к base32, используя 10 цифр и 22 строчные буквы, возможно, избегая очевидных проблем с опечатками, таких как 'o' 'i' 'l' и т. д.

EDIT

При дальнейшем изучении доступен Ruby base32 gem , который реализует реализацию Base 32 Дугласа Крокфорда

Строка Base32 из 5 символов может представлять более 33 миллионов целых чисел, а строка из 6 цифр - более миллиарда.

10 голосов
/ 18 сентября 2012

Если вы работаете с числами, вы можете использовать встроенные методы ruby ​​

6175601989.to_s(30)
 => "8e45ttj" 

чтобы вернуться

"8e45ttj".to_i(30)
=>6175601989

Так что вам не нужно ничего хранить, вы всегда можете декодировать входящий короткий код.

Это хорошо работает для подтверждения концепции, но вы не можете избежать неоднозначных символов, таких как: 1lji0o. Если вы просто хотите использовать код для обфускации идентификаторов записей базы данных, это будет работать нормально. В общем, короткие коды должны легко запоминаться и передаваться с одного носителя на другой, как, например, чтение их на слайде презентации или прослушивание по телефону. Если вам нужно избегать символов, которые плохо читаются или плохо слышат, вам может потребоваться переключиться на процесс, где вы генерируете приемлемый код, и сохраняете его.

0 голосов
/ 23 декабря 2013

Я нашел это коротким и надежным:

def create_uuid(prefix=nil)
  time   = (Time.now.to_f * 10_000_000).to_i
  jitter = rand(10_000_000) 
  key    = "#{jitter}#{time}".to_i.to_s(36)
  [prefix, key].compact.join('_')
end

Это выплевывает уникальные ключи, которые выглядят так: ' 3qaishe3gpp07w2m '
Уменьшите размер джиттера, чтобы уменьшить размер ключа.

Оговорка: Это не гарантированно уникально (используйте для этого SecureRandom.uuid), но это очень надежно:

10_000_000.times.map {create_uuid}.uniq.length == 10_000_000
0 голосов
/ 19 июля 2010

Единственный способ гарантировать уникальность - вести глобальный подсчет и увеличивать его для каждого использования: 0000, 0001 и т. Д.

...