2010-05-04 121 views
3

理论上,散列唯一值会产生一个唯一值吗?独特价值哈希值=唯一哈希值?

比方说,我有一个2列数据库表:id和代码。 id是一个自动递增的int,代码是一个varchar。如果我做...

$code = sha1($id); 

...然后将$ code存储到与$ id相同的行中。我的代码栏也是唯一的吗?

如果我追加当前时间,怎么办?例如:

$code = sha1($id . time()); 

谢谢。

+0

不能确定地说话,但我不认为你的散列可以保证是唯一的,因为sha1函数有#个输出。这表明由于有无限数量的潜在密钥,因此某些不同的密钥在加密时必须映射到相同的值。我不知道sha1算法的内部,所以我不能告诉你是否有任何数字beteween 1和你的数据库的数字列max val散列到相同的值。有人可能知道这个问题的答案,但我认为你会更好地使用不同的方法。 $ code = uniqid()? – 2010-05-04 19:11:37

+0

很感谢。我不知道uniqid(),我一定会看看。 – nebs 2010-05-04 19:16:39

回答

7

一般来说,答案是否定的。这很简单:SHA-1具有2^160个不同的输出 - 160位,但还有更多的输入(例如,有2^320个不同的40字节字符串,并且它们不能全部映射到独特的输出)。

给定一个足够的值子集,答案可能是。它取决于确切的算法和子集的大小:如果可能的输入数量小于可能的输出数量,则可能(但不能保证)。在考虑这一点时,记住birthday paradox可能会有所帮助:碰撞概率不会随输入数量线性增加。

+0

谢谢。因此获得唯一值的唯一方法是生成并扫描数据库以检查它是否存在(如果是,则重复)?这几乎是我试图避免在这里做的,但我想这是唯一的方法。 – nebs 2010-05-04 19:11:01

+0

不幸的是,如果你想保证一个独特的价值,没有别的办法。这也是为什么你不能轻松地反转哈希:我可以告诉你,“1”的SHA-1哈希是“356a192b7913b04c54574d18c28d46e6395428ab”,但是还有许多其他值会生成哈希。 – 2010-05-04 19:14:41

+0

我明白了。事情是我可能不需要产生超过1000个独特的值。在这种情况下,所有的价值观都是独一无二的,是否可以安全地说? – nebs 2010-05-04 19:16:08

-1

这取决于哈希算法。但理论上,除非散列与原始字符串完全相同,否则散列可能不是唯一的。

值的哈希值是原始值的精简表示。通过删除信息来创建哈希,您正在丢失使其在域中唯一的部分内容,因此增加了该值不唯一的可能性。唯一保证它是唯一的方法是使用原始值本身,这会破坏哈希的目的。

+0

“保证它是唯一的唯一方法就是使用原始价值本身” - 显然不是真的! – 2010-05-04 19:27:46

+0

@马丁 - 请解释一下你的意思,_why_是我的陈述不真实? – 2010-05-04 19:33:13

+0

哈希显然不一定是唯一性的原始字符串来保证。例如,它可能是原始字符串ROT13,并且仍然是唯一的。 – 2010-05-04 19:54:04

0

有两种不同的值给出相同散列的可能性很小。虽然很小,但不是不可能的。

-1

一个人不得不问这个问题,你为什么要这么做?如果你的数据库已经提供了一个唯一的标识符,为什么你需要生成另一个唯一的标识符?

你也可以考虑在PHP之外,如果你需要的话,许多数据库引擎会为你生成UUID样式的主键。

这里的重点是散列算法,如sha1()不适用于这种类型的工作;它们用于验证两个(可能非常长的)字符串输入是相同的。与类似但不精确的字符串相撞的机会非常遥远,但与非常不同的字符串碰撞的机会变得更高。

+0

为什么downvote? – 2012-08-21 13:47:42