2010-07-19 4 views
5

Je suis en train de générer des UUID avec le même style que urls bit.ly comme:Ruby on Rails - générer un style bit.ly UUID

http://bit.ly/aUekJP 

ou les CloudApp:

http://cl.ly/1hVU 

qui sont encore plus petits

comment puis-je le faire? J'utilise maintenant UUID gem pour ruby ​​mais je ne suis pas sûr s'il est possible de limiter la longueur et d'obtenir quelque chose comme ça. J'utilise actuellement ceci:

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

Mais je voudrais avoir encore plus petit et sachant que ce sera unique.

Toute aide serait très appréciée :)

Répondre

14

Vous confondez deux différentes choses ici. Un UUID est un identifiant universellement unique. Il a une très forte probabilité d'être unique même si des millions d'entre eux ont été créés dans le monde entier en même temps. Il est généralement affiché sous la forme d'une chaîne de 36 chiffres. Vous ne pouvez pas couper les 8 premiers caractères et attendre qu'il soit unique.

Bitly, tinyurl et-al stocke les liens et génère un code court pour représenter ce lien. Ils ne reconstruisent pas l'URL à partir du code qu'ils recherchent dans un magasin de données et retournent l'URL correspondante. Ce ne sont pas des UUIDS. Sans connaître votre application, il est difficile de vous conseiller sur la méthode que vous devriez utiliser, mais vous pouvez stocker ce que vous pointez dans un magasin de données avec une clé numérique, puis rebaser la clé de base32 en utilisant les 10 chiffres et 22 lettres minuscules, évitant peut-être les problèmes de typo évidents comme 'o' 'i' 'l' etc

EDIT

le complément d'enquête il y a un Ruby base32 gem disponible qui implémente Base 32 implementation de Douglas Crockford

a 5 caractère Base32 chaîne peut représenter plus de 33 millions d'entiers et une chaîne de 6 chiffres plus d'un milliard.

+0

merci pour l'information Steve, oui, je pense que j'ai vraiment mal compris le principe UUID:/la base32 gem semble très sympa, j'essaie juste de trouver une bonne façon de générer des URL courtes basées sur des ID d'enregistrement, j'utilise un ID de chaîne avant et lui assignant la méthode UUID, mais je pense maintenant que je peux revenir à un ID entier et si par exemple, commencer le comptage d'id à 363012 par exemple, j'obtiendrais une représentation de chaîne 'B2G4' pour cela. J'espère que cela pourrait suivre la même chose que ce que vous avez expliqué ci-dessus. – zanona

+0

@ludicco. C'est exactement ce que je disais. –

+0

@SteveWeet Merci pour votre base32 gem recommandé –

-10

La seule façon de garantir l'unicité est de maintenir un nombre global et incrémenter pour chaque utilisation: 0000, 0001, etc.

+3

Ce n'est pas la seule façon de garantir l'unicité. –

10

Si vous travaillez avec des chiffres, vous pouvez utiliser les méthodes intégrées de rubis

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

pour revenir en arrière

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

Vous ne devez pas stocker quoi que ce soit, vous pouvez toujours décoder un short_code entrant.

Cela fonctionne bien pour la preuve de concept, mais vous ne pouvez pas éviter les caractères ambigus tels que: 1lji0o. Si vous cherchez simplement à utiliser le code pour masquer les ID d'enregistrement de base de données, cela fonctionnera correctement. En général, les codes abrégés sont censés être faciles à retenir et à transférer d'un média à un autre, comme le lire sur la diapositive de présentation de quelqu'un ou l'entendre par téléphone. Si vous devez éviter les caractères difficiles à lire ou difficiles à "entendre", vous devrez peut-être passer à un processus dans lequel vous générez un code acceptable et le stocker.

+0

'to_i' accepte une base pouvant aller jusqu'à 36, de sorte que vous pouvez ajouter encore plus d'informations en quelques caractères. – jpadvo

0

Je trouve que ce soit à court et fiable:

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 

Ce recrache des clés uniques qui ressemblent à ceci: « 3qaishe3gpp07w2m »
Réduire la taille « de gigue » pour réduire la taille de la clé.

caveat: Ce n'est pas garantie unique, (utiliser SecureRandom.uuid pour cela), mais il est très fiable:

10_000_000.times.map {create_uuid}.uniq.length == 10_000_000