MD5是被广泛使用的密码散列函数,曾被广泛应用于计算机安全领域。在2004年,MD5被证实无法防止碰撞,因此不适用于安全性认证。那么MD5碰撞是什么意思,我们如何处理Hash碰撞呢?
简单来说,就是先得出一个字符串的MD5值,在根据这个值,逆算出另外一个不同的字符串,但是它们的MD5值是一致的。这就是MD5碰撞,几率很小的。
我们常见的碰撞法:暴力碰撞(穷举法、字典法),就是利用计算机的资源尝试碰撞已知的MD5码。
1、穷举法
穷举法就是不停地尝试各种字符的排列组合,看哪一个组合的MD5码能对上。缺点是太耗费时间。举个例子,假设我们要破解一个6位大小写字母和数字混合的密码,那么一***有 (26 + 26 + 10) ^ 6 种组合。这个数的大小超过500亿。
2、字典法
字典法就是把计算结果以映射表的形式存放起来,一个原文对应着一个MD5值。将已知的MD5码查表,就可直接反查出原文。字典法体现了算法设计的“以空间换时间”的思想。缺点是比较耗费空间,而且实际上还是要穷举一遍所有的输入,只不过把穷举的结果存了起来。
一个用字典法实现md5解密的网站:/
通常有两类方法处理碰撞:开放寻址(Open Addressing)法和链接(Chaining)法。前者是将所有结点均存放在散列表T[0..m-1]中;后者通常是把散列到同一槽中的所有元素放在一个链表中,而将此链表的头指针放在散列表T[0..m-1]中。
1、开放寻址法
所有的元素都在散列表中,每一个表项或包含动态集合的一个元素,或包含NIL。这种方法中散列表可能被填满,以致于不能插入任何新的元素。在开放寻址法中,当要插入一个元素时,可以连续地检查或探测散列表的各项,直到有一个空槽来放置待插入的关键字为止。有三种技术用于开放寻址法:线性探测、二次探测以及双重探测。
线性探测法适用场景
在 Java 中的 ThreadLocalMap 就是采用了开放寻址法来解决哈希冲突,因为开放寻址法在极端环境下时间复杂度会退化成 O(n),所以适用于数据量较少的场景。
2、链地址法
链地址法也叫链表法,这种方法比较常见也比较简单,就是插入一个元素时,如果发现当前位置已经有元素,则以当前节点为头节点(尾插法)或者尾结点(头插法)构造一个链表,如果进一步优化的话,可以将链表修改为红黑树等数组结构,比如 jdk 1.8 之后的 HashMap 就是采用的这种方式进行优化。
链地址法适用场景
基于链表的哈希冲突处理方法比较适合存储大对象、大数据量的哈希表,因为链表本身就需要额外的空间来存储指针地址,所以如果一个节点存储的数据大小还没有指针大,那就会造成很大空间浪费;相反,如果指针的大小相对于数据大小可以忽略,那用链地址法解决冲突会是一个比较好的选择,而且链地址法会更加灵活,支持更多的优化策略,比如 HashMap 中当链表节点数大于 8 就会转化为红黑树来进行优化。
本文介绍了MD5碰撞是什么意思,以及Hash碰撞处理的方法:开放寻址法和链地址法。并且,介绍了线性探测法和链地址法的应用场景。通过以上的介绍,大家应该对这些问题有了一定的了解,更多关于MD5的知识可以在往期文章中查阅哦。