2011-02-17 26 views
6

Estoy intentando crear cadenas cortas que no colisionen con cadenas más largas en Ruby. ¿Cuál es la mejor manera de hacer esto? ¿Base64 codifica un hash MD5?¿Cuál es la mejor forma de generar una cadena de hash corta a partir de una cadena más larga?

Este es el caso de uso:

loop do 
    key = short_hash("#{user_id}-#{timestamp}") 
    break if $redis.setnx(key, "0") 
end 

no quiero clave para ser demasiado largo.

+0

Hay un montón de preguntas en este sitio sobre temas similares. Intenta buscar temas hash. Aquí hay uno: http://stackoverflow.com/questions/4066601/developing-a-url-shortener/4066615#4066615 –

+1

@Sugerman: Esa pregunta está en Python. –

+2

Lo que puede deducir de la respuesta en ese (y otros) hilos si los lee es que la "mejor manera" de hacer esto es independiente del idioma. Primero elija su algoritmo hash y luego preocúpese por la implementación específica del idioma. –

Respuesta

4

A menudo utilizo un SHA tiene para esto similar al ejemplo que tiene. No está garantizado que ser único, pero por lo general es lo suficientemente bueno para la mayoría de los propósitos:

require 'digest/sha1' 
Digest::SHA1.hexdigest("#{user_id}-#{Time.now.to_i}-#{rand}") 

El ruby UUID gem es otra opción.

Pero en su caso específico ya que está usando redis, ¿por qué no simplemente utiliza el comando redis INCR? Entonces puede garantizar la singularidad al menos dentro de su base de datos. Por ejemplo:

unique_key = $redis.incr('users:next') 
+0

Hmm. Estaba pensando en usar 'incr', pero necesito almacenar un valor para la unique_key ... Creo que podría hacer' uid = $ r.incr ('uids'); $ r.set (uid, value) ' –

+0

Así que terminé yendo con' incr', pero en cuanto a mi pregunta original, esperaba tener un hash más corto que 'Digest :: SHA1.hexdigest'. Creo que podría usar la codificación base64 ... –

4

Puede usar una función hash para crear cadenas más cortas que no sean probable colisionar. Sin embargo, el Pigeonhole principlegarantiza que podrá encontrar dos cadenas más largas que harán un hash con el mismo valor.

Para generar valores realmente únicos, es posible que deba asignar un número de identificación secuencial. Pero esto también requeriría que realice un seguimiento de qué número de identificación ha asociado con cada cadena de entrada.

+0

Lo siento, olvidé mencionar que revisaré las colisiones y volveré a intentarlo. Solo quiero evitar "reintentos" tanto como sea posible. –

Cuestiones relacionadas