在我的代码中,我正在生成 URL 的散列(实际上是无限长度的)。我目前正在使用 sha1(),我知道它发生冲突的可能性很小,但是我有多达 255 个字节来存储哈希,所以我觉得我不妨利用可用空间来降低冲突的可能性更远。
是否有:
- 另一个具有更长或可自定义哈希长度的 PHP 哈希函数?
- 使用带有可变长度输入的 sha1 等固定长度哈希函数来生成更长哈希的方法?
或者,sha1 的 20 字节散列对任何事情都足够好,我应该停止担心它吗?
或者,sha1 的 20 字节对任何事情都足够好,我应该停止担心吗?
确切地。
哈希表、鸽洞和生日
http://www.codinghorror.com/blog/archives/001014.html
让我们看看... http://www.cryptography.com/cnews/hash.html
问:在 SHA-1 中找到冲突有多难?
答:报告的攻击需要估计工作因子为 2^69(约 5900 亿)的哈希计算
看起来风险很低...^_^
如果您真的很担心,请选择 256 位或 512 位哈希(32 或 64 个字符)。
如果您真的非常偏执,请加盐。
如果您比这更偏执,请将两个散列连接成一个更长的散列,例如 md5 和 sha-256。
您总是可以在现有哈希之前/附加一个顺序 ID(十进制或十六进制)?
当然,您不会有固定长度的哈希,但您会知道代码是 a) 唯一且 b) 不可猜测(即使有人注意到顺序部分,他们也不知道您对其余部分进行加盐/散列的方式编码)。
当然,如果您不想向任何人隐藏这些哈希值,那么为什么不首先简单地使用顺序 ID?
由于我不确切知道您要做什么,因此我假设您不想输入两次数据,并且希望能够快速检测碰撞。在这种情况下,我用伪代码提出以下算法:
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 决定接受或拒绝。这将允许您使用更短的散列函数。大概您已经存储了 url 以供以后使用,因此这不会涉及任何额外的存储。
如果你真的想对它着迷,你可以做的是结合 URL 不同部分的哈希值。
假设 URL 有 40 个字符长 - 将其分成 5 部分:获取字符 1-8 的 SHA1,连接到字符 9-16 的 SHA1,连接到 17-24 的 SHA1 ......等等。理论上你会然后有 2 800 种可能性,并且只需要在 2 (69*5) = 2 345 = 7.2 * 10 103行之后开始担心冲突。
但就像我说的,我们正用这样的方法直奔疯狂的小镇。
好吧,只有当你有一个短哈希键时才有意义。否则存在表中数据溢出的风险。