Hash 如何计算截断散列时对冲突概率的影响?

Hash 如何计算截断散列时对冲突概率的影响?,hash,md5,probability,collision,Hash,Md5,Probability,Collision,我希望将MD5摘要从32个字符减少到16个字符,理想情况下更接近16个字符。我将使用它作为数据库键来检索一组(公共)用户定义的参数。我预计唯一“ID”的数量最终将超过10000个。碰撞是不可取的,但不是世界末日 我想了解对MD5摘要进行简单的截断以获得更短的密钥的可行性。但我很难找到一个我能理解的公式(因为我的数学背景有限),更不用说用它来确定截断散列对碰撞概率的影响了 越短越好,这是合理的。我觉得一定有一个简单的公式,但我宁愿有一个明确的答案,也不愿自己根据我在网上读到的点点滴滴拼凑起来进行猜

我希望将MD5摘要从32个字符减少到16个字符,理想情况下更接近16个字符。我将使用它作为数据库键来检索一组(公共)用户定义的参数。我预计唯一“ID”的数量最终将超过10000个。碰撞是不可取的,但不是世界末日

我想了解对MD5摘要进行简单的截断以获得更短的密钥的可行性。但我很难找到一个我能理解的公式(因为我的数学背景有限),更不用说用它来确定截断散列对碰撞概率的影响了


越短越好,这是合理的。我觉得一定有一个简单的公式,但我宁愿有一个明确的答案,也不愿自己根据我在网上读到的点点滴滴拼凑起来进行猜测。

你可以用这个公式计算碰撞的几率:

chance of collision = 1 - e^(-n^2 / (2 * d))
其中,
n
是消息数,
d
是可能性数,
e
是常数
e
(2.718281828…)

太棒了

我发现了其他一些或多或少精确和/或简化的方程式,以及一个很好的解释和对现实世界概率的方便比较:

  • 一,−e^((−k(k−1) )/2N)-
  • (k(k-1))/2N-
  • k^2/2N-
…其中,
k
是您将生成的ID数(“消息”),而
N
是哈希摘要可以生成的最大数,或者是截断的十六进制数可以表示的最大数(技术上是+1,表示0)


关于“N”的更多信息 例如,如果您的原始散列是“38BF05A71DDFB28A504AFB083C29D037”(32个十六进制字符),并且您将其截断为12个十六进制字符(例如:“38BF05A71DDF”),那么您可以在十六进制中生成的最大数字是“0xFFFFFFFFFF”(281474976710655-这是16^12-1(或者256^6,如果您更愿意用字节来考虑)。但是由于“0”它本身就是你理论上可以产生的数字之一,你把1加回去,剩下的就是16^12


因此,您可以将
N
视为16^(numberOfHexDigits)。

请记住,通过将基数为16的哈希值更改为较大的基数,也可以大大缩短哈希值。例如,基数为62(上限、下限和数字)将md5哈希字符串从32个字符减少到21或22个字符。感谢@Jonathan,我确实读过这篇文章,并尝试使用在线base62编码器进行一个小测试,但结果总是比原始哈希长几个字符。例如:但可能他们做得不对?您需要指定输入基数16,这就是哈希是。如果不这样做,则很可能使用所有标准ascii字符,并将基数从256->62减少,而不是从16->62增加基数。增加基数可以节省字符。当测试允许您设置输入和输出基数时。很好的一点是,您可以在不减少冲突的情况下使用它基于md5哈希的/唯一性/精度。您甚至可以使用自己的基本转换器(有大量的userland实现)使用额外的符号来增加基数,并达到目标15个左右的字符。让我们看看我是否正确:如果我有,比如说,10000个我想要生成的ID,并且假设我将我的十六进制散列值截断为8个字符,那么等式变成:
1-e^(-10000^2/(2*16^8))
=~0.01157403..`或大约1.1%的碰撞概率?