使用哈希作为唯一ID是错误的吗?

时间:2013-05-03 05:29:38

标签: php hash

我想在数据库表中使用PHP生成的唯一ID,该表可能永远不会超过10,000条记录。我不希望创建时间可见或使用纯数值,所以我使用:

sha1(uniqid(mt_rand(), true))

将哈希用于唯一ID是错误的吗?不是所有的哈希都会导致碰撞,或者是否有机会如此遥远以至于在这种情况下不应该考虑它们?

还有一点:如果要散列的字符数小于sha1散列中的字符数,它是否总是唯一的?

5 个答案:

答案 0 :(得分:6)

如果你有2个键,你将得到一个理论上最好的情况,即1 ^ 2 ^ X碰撞概率,其中X是你的散列算法中的位数。最好的情况是输入通常是ASCII,它不使用完整的字符集,加上散列函数不能完美分配,所以它们会比现实生活中的理论最大值更频繁地发生碰撞。

回答你的最后一个问题:

  

另一点:如果要散列的字符数小于   sha1哈希中的字符数不一定是唯一的吗?

是的,这是真的。但是你会遇到另一个生成该大小的唯一键的问题。最简单的方法通常是校验和,所以只需选择一个足够大的摘要,使碰撞空间足够小,以便您舒适。

正如@wayne所建议的,一种非常常用的方法是将microtime()连接到随机盐(和base64_encode以提高熵)。

答案 1 :(得分:3)

如果两个人的结局相同,会有多可怕?墨菲定律适用 - 如果百万比一,甚至100,000:1的机会是可以接受的,那么就去吧!真正的机会要小得多,但是如果你的系统发生爆炸,那么你的设计缺陷必须先解决。然后自信地继续。

以下是概率的真实问题:Probability of SHA1 Collisions

答案 2 :(得分:3)

使用sha1(time())代替,然后只要时间可以表示比sha1哈希短,就可以删除重复哈希的随机可能性。 (可能比你填写更长的时间找到一个工作的php解析器;))

答案 3 :(得分:2)

计算机随机实际上并不是随机的,你知道吗? 假设您在Unix环境中,您可以从计算机获得的唯一真正随机来自/dev/random,但这是一种阻止操作,取决于用户交互,如移动鼠标或在键盘上键入。从/dev/urandom读取不太安全,但最好只使用ASCII字符,并为您提供即时响应。

答案 4 :(得分:0)

sha1($ipAddress.time()) 导致任何人不可能同时使用同一个IP地址