考虑使用简单的散列来创建内部使用的缩短URL服务。我计划使用的功能如下
string s = base64Convert(md5(salt: time in million seconds))
string url = s.substring(0, len: 6)
Map url to real url
将有64 ^ 6 = 68,719,476,736种可能的组合。对我们的内部服务来说应该足够了。
然而有一点让我担心的是,我怎样才能确保在64 ^ 6 + 1时间散列之前不会有重复的网址?
有什么想法吗?
答案 0 :(得分:3)
如何确保在64 ^ 6 + 1时间哈希之前不会有重复的网址?
使用简单散列,您无法确保此属性。
假设md5的等分布,如果你有 n 网址进行哈希并再添加一个,那么 n 可能会产生如何碰撞的结果和64 6 < / sup> - n 它不会发生碰撞的方式。因此,新元素发生碰撞的可能性为 n / 64 6 。即使 n = 1,该值也不为零,因此第二个URL在理论上可能已经发生冲突,即使实际发生这种情况的可能性非常低。您的数据库中的非碰撞URL越多,新散列与任何现有散列冲突的可能性就越高,直到 n = 64 6 <的机会变为100% / SUP>
如果您这样想,请务必记住birthday “paradox”。如果您要添加一组 n 网址,那么它们中的任何两个碰撞的可能性方式大于只有最后一个碰撞你之前添加的任何一个的可能性。如果您do the math,您会发现使用您的方案,您可以在其中任意两个之间发生冲突的机会超过1%之前散列大约37.000个网址。
所以你现在必须决定1%的碰撞几率是否可以接受,以及37.000个URL是否足以满足你的需要。如果概率结果不满足您,您可以通过例如调整机会来调整机会。使用超过6位数字,或者您必须实施collision resolution。