2008-09-15 363 views
16

我在写一个指向外部链接的web应用程序。我正在为每个可以在URL中使用的文档创建一个非顺序的,不可猜测的ID。我做了一件显而易见的事情:把url当作一个字符串和str#crypt来处理,但是它似乎扼杀了任何非字母数字字符,如斜线,点和下划线。什么是红宝石网址的最佳方式?

有关解决此问题的最佳方法的任何建议?

谢谢!

回答

35

取决于你想一个字符串多久,你可以使用一些替代方案:

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" 

请注意,这不会是不可猜测,您可能必须将其与其他一些(秘密但静态的)数据结合起来以便对字符串加盐:

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

现在,对于不知道原始内容且无法访问源代码的用户生成此散列变得更加困难。

0

使用Digest::MD5从Ruby的标准库:

Digest::MD5.hexdigest(my_url) 
3

我还建议看看摘要命名空间中的不同算法。为了使它更难猜测,而不是(或除了)与秘密口令腌制,也可以使用的时间精确转储:

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

由于任何散列算法的结果不能保证是独一无二的,不要忘记在假设你的散列可用之前检查你的结果对先前生成的散列的唯一性。 Time.now的使用使重试变得不重要,因为你只需要调用直到生成一个唯一的哈希。