2008-09-15 8 views
16

J'écris une application web qui pointe vers des liens externes. Je cherche à créer un identifiant non-séquentiel, non-devinable pour chaque document que je peux utiliser dans l'URL. J'ai fait la chose évidente: traiter l'url comme une chaîne de caractères et une chaîne de caractères, mais cela semble étouffer tous les caractères non alphanumériques, comme les barres obliques, les points et les traits de soulignement.Quelle est la meilleure façon de hacher une url en rubis?

Des suggestions sur la meilleure façon de résoudre ce problème?

Merci!

Répondre

35

Selon combien de temps une chaîne que vous souhaitez, vous pouvez utiliser quelques alternatives:

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" 

Notez que ce ne sera pas unguessable, vous devrez peut-être le combiner avec d'autres données (secrètes mais statiques) pour saler la chaîne:

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

Maintenant, il devient beaucoup plus difficile de générer ce hachage pour quelqu'un qui ne connaît pas le contenu original et n'a pas accès à votre source.

0

Utilisation Digest::MD5 de la bibliothèque standard de Ruby:

Digest::MD5.hexdigest(my_url) 
3

Je suggère également d'examiner les différents algorithmes dans l'espace de noms digest. Pour le rendre plus difficile à deviner, plutôt que (ou en plus) le salage avec un mot de passe secret, vous pouvez également utiliser une décharge précise du temps:

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

Depuis le résultat d'un algorithme de hachage n'est pas garanti Soyez unique, n'oubliez pas de vérifier l'unicité de votre résultat par rapport aux hachages générés précédemment avant de supposer que votre hachage est utilisable. L'utilisation de Time.now rend le réessai trivial à implémenter, puisqu'il suffit d'appeler jusqu'à ce qu'un hachage unique soit généré.

Questions connexes