2008-09-15 12 views
16

Estoy escribiendo una aplicación web que apunta a enlaces externos. Estoy buscando crear una identificación no secuencial e inadvertida para cada documento que pueda usar en la URL. Hice lo más obvio: tratar la url como una cadena y str # crypt, pero parece ahogarse con los caracteres no alfanuméricos, como las barras, los puntos y los guiones bajos.¿Cuál es la mejor manera de hash una url en ruby?

¿Alguna sugerencia sobre la mejor manera de resolver este problema?

Gracias!

Respuesta

35

Dependiendo de cuánto tiempo una cadena que desea puede utilizar algunas alternativas:

require 'digest' 
Digest.hexencode('http://foo-bar.com/yay/?foo=bar&a=22') 
# "687474703a2f2f666f6f2d6261722e636f6d2f7961792f3f666f6f3d62617226613d3232" 

require 'digest/md5' 
Digest::MD5.hexdigest('http://foo-bar.com/yay/?foo=bar&a=22') 
# "43facc5eb5ce09fd41a6b55dba3fe2fe" 

require 'digest/sha1' 
Digest::SHA1.hexdigest('http://foo-bar.com/yay/?foo=bar&a=22') 
# "2aba83b05dc9c2d9db7e5d34e69787d0a5e28fc5" 

require 'digest/sha2' 
Digest::SHA2.hexdigest('http://foo-bar.com/yay/?foo=bar&a=22') 
# "e78f3d17c1c0f8d8c4f6bd91f175287516ecf78a4027d627ebcacfca822574b2" 

Tenga en cuenta que esto no será imposible de adivinar, puede que tenga que combinarlo con algunos otros datos (secretos pero estáticos) para eliminar la cadena:

salt = 'foobar' 
Digest::SHA1.hexdigest(salt + 'http://foo-bar.com/yay/?foo=bar&a=22') 
# "dbf43aff5e808ae471aa1893c6ec992088219bbb" 

Ahora se vuelve mucho más difícil generar este hash para alguien que no conoce el contenido original y no tiene acceso a su fuente.

0

Uso Digest::MD5 de la biblioteca estándar de Ruby:

Digest::MD5.hexdigest(my_url) 
3

También sugiero mirar los diferentes algoritmos en el espacio de nombres de resumen. Para que sea más difícil de adivinar, en lugar de (o además de) la salazón con una frase de contraseña secreta, también se puede utilizar un vertedero precisa del tiempo:

require 'digest/md5' 
def hash_url(url) 
    Digest::MD5.hexdigest("#{Time.now.to_f}--#{url}") 
end 

Puesto que el resultado de cualquier algoritmo de hash no se garantiza que Sea único, no se olvide de verificar la singularidad de su resultado contra los hashes generados previamente antes de asumir que su hash es utilizable. El uso de Time.now hace que el reintento sea trivial para implementar, ya que solo tiene que llamar hasta que se genere un hash único.

Cuestiones relacionadas