2010-07-19 2 views
5

Я пытаюсь создать UUID, с тем же стилем, как bit.ly URLs, как:Рубин на Rails - генерации bit.ly стиль UUIDs

http://bit.ly/aUekJP 

или CloudApp из них:

http://cl.ly/1hVU 

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

как я могу это сделать? Теперь я использую жемчужину UUID для рубина, но я не уверен, что можно ограничить длину и получить что-то вроде этого. настоящее время я использую это:

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

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

Любая помощь будет очень высоко ценится :)

ответ

14

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

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

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

EDIT

На доследование есть рубин base32 gem доступны, который реализует Douglas Крокфорд-х Base 32 implementation

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

+0

спасибо за информацию Стив, да, я думаю, что я действительно неправильно понял принцип uuid:/base32 gem кажется очень приятным, я просто пытаюсь найти правильный способ генерировать короткие URL-адреса на основе идентификаторов записей, я использовал string ID и назначить ему метод UUID, но теперь я могу вернуться к идентификатору целого числа, а затем, если, например, запустив счетчик id 363012, я бы получил строковое представление «B2G4» для него. Я надеюсь, что это может следовать так же, как вы объяснили выше. – zanona

+0

@ludicco. Это именно то, что я говорил. –

+0

@SteveWeet Спасибо за ваш рекомендуемый камень base32 –

-10

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

+3

Это не единственный способ гарантировать уникальность. –

10

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

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

вернуться

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

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

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

+0

'to_i' принимает радикс высотой 36, поэтому вы можете упаковать еще больше информации на несколько символов. – jpadvo

0

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

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 
Смежные вопросы