首页 > 编程知识 正文

二维碰撞,hash函数碰撞问题

时间:2023-05-04 23:33:56 阅读:16163 作者:4867

如果两个输入字符串的散列函数值相同,则这两个字符串称为“碰撞”。 既然将任意长度的字符串设为固定长度的字符串,就必然有一个与无限多个输入列对应的输出列,冲突必然存在。

优秀的散列函数f必须满足以下三个条件:

)对于任意y,按f(x )=y的方式查找x在计算上是不可能的。

)2)给出x1A,查找x2B,使得f(x1 ) f(x1 )在计算上不可行。 也就是说没有弱的冲突性。

)3)寻找x1,x2,使得f(x1 ) f(x1 )在计算上也不可能。 也就是说没有很强的冲突性。

这样被称为安全散列函数,除了枚举以外没有更快的方法。 如第3条,根据生日定理,要找到这样的x1、x2,理论上需要约2^(n/2 )的列举次数。

由于前两个可以破坏的散列函数太弱而被丢弃,大多数散列函数的解密意味着破坏了前面的第三性质,即找到冲突。 密码学中另一个概念是理论解读,这意味着提出一种算法,能够以低于理论的枚举次数找到冲突。

4、冲突处理

通常,有两种处理冲突的方法:“开放地址方法”(Open Addressing )和“链接方法”(Chaining )。 前者将所有节点存储在哈希表T[0.m-1]中; 后者通常将在同一插槽中散列的所有元素放在一个链表中,并将此链表的头指针放在哈希表T[0.m-1]中。

(1)开放地址法

所有元素都位于哈希表中,每个表条目都包含包含动态集合的元素或NIL。 这可能会导致哈希表已满,无法插入新元素。 在开放地址方法中,插入元素时,可以连续检查或探测哈希表中的项目,直到有空插槽用于放置要插入的关键字。 开放地址法有线性检测、二次检测、双重检测三种技术。

1线性探测器

给定常规散列函数h ':u-{ 0,1,m-1},在线性检测方法中,使用h(k,I ) k ) I ) mod m,I=0,1,m-1 )

:14px; line-height:20.8799991607666px">      探测时从i=0开始,首先探查T[h'(k)],然后依次探测T[h'(k)+1],…,直到T[h'(k)+m-1],此后又循环到T[0],T[1],…,直到探测到T[h'(k)-1]为止。探测过程终止于三种情况: 
  (1)若当前探测的单元为空,则表示查找失败(若是插入则将key写入其中); 
  (2)若当前探测的单元中含有key,则查找成功,但对于插入意味着失败; 
  (3)若探测到T[h'(k)-1]时仍未发现空单元也未找到key,则无论是查找还是插入均意味着失败(此时表满)。

  线性探测方法较容易实现,但是存在一次群集问题,即连续被占用的槽的序列变的越来越长。采用例子进行说明线性探测过程,已知一组关键字为(26,36,41,38,44,15,68,12,6,51),用除余法构造散列函数,初始情况如下图所示:

散列过程如下图所示:

<2>二次探测

   二次探测法的探查序列是:h(k,i) =(h'(k)+i*i)%m ,0≤i≤m-1 。初次的探测位置为T[h'(k)],后序的探测位置在次基础上加一个偏移量,该偏移量以二次的方式依赖于i。该方法的缺陷是不易探查到整个散列空间。

<3>双重散列

  该方法是开放寻址的最好方法之一,因为其产生的排列具有随机选择的排列的许多特性。采用的散列函数为:h(k,i)=(h1(k)+ih2(k)) mod m。其中h1和h2为辅助散列函数。初始探测位置为T[h1(k)],后续的探测位置在此基础上加上偏移量h2(k)模m。

 (2)链接法

  将所有关键字为同义词的结点链接在同一个链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于1,但一般均取α≤1。

  举例说明链接法的执行过程,设有一组关键字为(26,36,41,38,44,15,68,12,6,51),用除余法构造散列函数,初始情况如下图所示:

最终结果如下图所示:


版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。