2010-07-19 7 views
5

estoy tratando de generar UUID con el mismo estilo que las direcciones URL bit.ly como:Ruby on Rails - generando estilo bit.ly UUID

http://bit.ly/aUekJP 

o CloudApp los:

http://cl.ly/1hVU 

cuales son aún más pequeños

¿cómo puedo hacerlo? Ahora estoy usando la gema UUID para rubí, pero no estoy seguro de si es posible limitar la longitud y obtener algo como esto. Actualmente estoy usando esto:

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

Pero me gustaría tener aún más pequeño y sabiendo que va a ser único.

Cualquier ayuda sería muy apreciada :)

Respuesta

14

Usted está confundiendo dos cosas diferentes aquí. Un UUID es un identificador universal único. Tiene una alta probabilidad de ser único, incluso si millones de ellos se están creando en todo el mundo al mismo tiempo. Generalmente se muestra como una cadena de 36 dígitos. No puede cortar los primeros 8 caracteres y esperar que sea único.

Bitly, tinyurl et-al almacenan enlaces y generan un código corto para representar ese enlace. No reconstruyen la URL del código que buscan en un data-store y devuelven la URL correspondiente. Estos no son UUIDS.

Sin conocer su aplicación, es difícil aconsejar sobre el método que debe usar, sin embargo, puede almacenar lo que esté apuntando en un almacén de datos con una clave numérica y luego volver a establecer la clave en base32 usando los 10 dígitos y 22 letras minúsculas, tal vez evitando los problemas typo obvias como 'o' 'i' 'l', etc

EDITAR

En una investigación adicional hay un rubí base32 gem disponibles que implementa de Douglas Crockford Base 32 implementation

a 5 personaje Base32 cadena puede representar más de 33 millones de enteros y una cadena de 6 dígitos de más de mil millones.

+0

gracias por la información Steve, sí, creo que realmente entendí mal el principio de uuid:/la gema de base32 parece muy bonita, solo estoy tratando de encontrar una forma adecuada de generar URL cortas basadas en identificaciones de registros, estaba usando una cadena ID antes y asignarle el método UUID, pero creo que ahora puedo volver a una ID entera y luego, por ejemplo, iniciar el conteo de id en 363012 por ejemplo, obtendría una representación de cadena 'B2G4' para él. Espero que esto pueda seguir el mismo que has explicado anteriormente. – zanona

+0

@ludicco. Eso es exactamente lo que estaba diciendo. –

+0

@SteveWeet Gracias por su gema base32 recomendada –

-10

La única manera de garantizar la unicidad es mantener un recuento global y se incrementará para cada uso: 0000, 0001, etc.

+3

Esa no es la única manera de garantizar la unicidad. –

10

Si está trabajando con números, se puede utilizar el construido en los métodos de rubí

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

para volver

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

Así que usted no tiene que guardar cualquier cosa, siempre se puede decodificar un short_code entrante.

Esto funciona bien como prueba de concepto, pero no puede evitar caracteres ambiguos como: 1lji0o. Si solo desea utilizar el código para ocultar las identificaciones de registro de la base de datos, esto funcionará correctamente. En general, se supone que los códigos cortos son fáciles de recordar y transferir de un medio a otro, como leerlo en la diapositiva de presentación de alguien o escucharlo por teléfono. Si necesita evitar caracteres que son difíciles de leer o difíciles de "escuchar", es posible que deba cambiar a un proceso donde genere un código aceptable y almacenarlo.

+0

'to_i' acepta una base de hasta 36, ​​por lo que puede incluir aún más información en unos pocos caracteres. – jpadvo

0

Me pareció que para ser corto y 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 

Este escupe claves únicas que se ven así: '3qaishe3gpp07w2m'
Reducir el tamaño 'jitter' para reducir el tamaño de la clave.

Advertencia: esto no está garantizado único (SecureRandom.uuid utilizar para eso), pero es altamente fiable:

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