2008-11-17 69 views
3

在我的代码中,我生成了URL的哈希值(实际上是无限长的)。我目前使用的是sha1(),我知道它有一个很小的碰撞机会,但是我有多达255个字节来存储散列值,所以我觉得我可以使用可用空间来降低碰撞的几率进一步。输出长度长的PHP哈希函数?

有两种:

  1. 另一个PHP哈希函数具有较长的或定制的哈希长度?
  2. 使用固定长度的散列函数(如sha1和可变长度输入以生成更长的散列)的方法?

或者,sha1的20个字节的哈希值足够用于任何事情,我应该不再担心它了吗?

回答

5

或者,sha1的20字节是否足够满足任何需求,我应该不再担心它了?

没错。

哈希表,鸽巢,以及生日
http://www.codinghorror.com/blog/archives/001014.html

+0

生日悖论正是我所担心的 - 我不想让舞台上有几十万行的碰撞几率变得不可忽略。鉴于我有足够的字节来存储更长的散列的豪华应该不使用,如果可用? – 2008-11-17 13:14:55

1

如果你真的担心,选择一个256或512位的散列(32个或64个字符)。

如果你真的,真的偏执,加一个盐。

如果你比这更偏执,将两个哈希连接成一个较长的哈希,比如md5和sha-256。

+0

听起来像这个系统正在被用来防止重复的网址被输入......如果是这样的话,有盐会破坏目的。 – Powerlord 2008-11-17 13:30:45

0

你总是可以在你现有的散列上加上/附加一个序列ID(十进制或十六进制)吗?

确定你不会有一个固定长度的散列,但你会知道代码是独特的和b)不可猜测的(即使有人注意到顺序部分,他们不会知道你腌制/散列其余的代码)。

当然,如果你不试图隐藏任何人的这些哈希值,那么为什么不简单地使用序列号呢?

0

由于我不确切知道你在做什么,因此我会假设你不想两次输入数据,并且希望能够快速检测到冲突。在这种情况下,我建议在伪代码如下算法:

found = false 
hv = hash(urlValue) 
if table[hash,url] contains pair (hv,urlValue) 
    found = true 
endif 

if (not found) 
    insert table (hv,urlValue) 
endif 

在数据库中创建的哈希列非唯一索引,以加快查找窗口。这将允许(hash,url)上的查询快速进行 - 在通常情况下,您只查看一行,因为散列可能是唯一的,但是您确实决定接受或拒绝基于实际url。这将允许您使用较短的散列函数。据推测,您已经存储了网址供以后使用,所以这将不涉及任何额外的存储。

0

如果你想让它变得非常疯狂,你可以做的是结合URL的不同部分的哈希值。

假设网址长度为40个字符 - 将其分成5个部分:获取字符1-8的SHA1,连接到字符9-16的SHA1,连接到17-24的SHA1 ...等。理论上讲,你会再有2点的可能性,只需要启动后2 (69 * 5) = 2 = 7.2×10个行担心冲突。

但是就像我说的,我们正在用这种方法直奔疯狂的小镇。

0

那么,它只有在你有小键盘哈希键时才有意义。否则,表中有数据溢出的风险。