版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/luo4105/article/details/103142144
在java中,默认使用hashCode生成对象的hash值,它在一定程度上可以作为对象的唯一表示。同时还有MD5,SHA-1这些也可以计算文件/对象的hash值,标志唯一,那它们之间有什么区别呢。
hashcode,md5,SHA-1都是散列加密算法,其中hashcode长度为32位,md5为128位,sha-1为160位。位数越大,这个数据的数据量就越大,重复的几率越小,但是运算起来越复杂,消耗的计算资源越多。所以重复性来比较,hashcode > md5 > sha-1,而按计算消耗性能来比较hashcode < md5 < sha-1。即hashcode最容易出现重复,消耗性能最小。那么最容易出现重复具体量化是多少呢,是否有计算公式呢,实际是有的。著名的生日驳论就是描述这个数学现象的问题。
为什么会重复? 重复原因是随着新的元素越来越多,集合中存在重复的几率也越越来越大,如容量为10的集合,随机进一个数不重复的概率是1,在进一个数不重复的概率就是1/10,数越多,概率越大。
生日驳论是指,如果在一个房间要多少人,则两个人的生日相同的概率要大于50%? 答案是23人。 计算规则是让23个人依次进入,那么每个人生日都与其他人不同的概率依次是1,364/365,363/365,362/365,361/365,等等。先进入房间的这些人生日两两不同的概率是很大的,比如说前面5个是1×364/365×363/365×362/365×361/365=97.3%。而对于最后进入房间的几个人情况就完全不同。最后几个人进入房间并且找不到同生日者的概率是… 345/365,344/365,343/365
我们计算一下hashcode,md5,SHA-1的冲突率达到10%时的数量。
hashcode长度为32为,容积为2312^{31}231,
代码语言:javascript复制import sys
sys.setrecursionlimit(90000)
capacity = 2147483648;
def notEqluasPR(num, lastPR) :
PR = (2147483648-num)/2147483648 * lastPR;
if PR < 0.9 :
return num;
return notEqluasPR(num 1,PR);
print(notEqluasPR(2,1))
输出
代码语言:javascript复制21272
当hashcode的对象数超过2万时,不重复的几率不到90%了。
数据量达到1w,不重复率0.9769835851579908
数据量达到3w,不重复率0.8109445986601609
可以得出结论,如果数据过万,采用hashcode的方式将会有hash碰撞风险。
md5
md5有128位,即21272^{127}2127,这个数太大,一赋值我的python3就奔溃了,我查询了一下,大约是个天量数字,基本可以作为一个文件唯一码的效验。
sha-1位数比md5还大,也不计算了。
结论
当对象个数超过1w时,hashcode就会有碰撞的可能;在自然情况下,使用md5就可以唯一码的效验,基本不会发生重复;考虑到md5已被破解,对外发布的效验码,可以使用SHA-1效验码。