关于散列数查表问题

 实际存储方式有问题。
首先要明白一个概念性的问题:
加密只有解密(破解)的问题,散列只有碰撞(伪造)的问题。


对于一个散列数,实际碰撞会很多的,且有一定规律可寻,正如王晓云教授找到MD5碰撞的规律。


我们可以用一个日常生活来举例,攻破巨型数据库查表问题:


某日必定对应一个星期,例如今天是周一。
星期的周期是7天,即每7天为某星期几。
但是星期几却不知是具体的某日。


假若用数据库来存储星期散列数0~6(周日周一~周六),那么要存储多少日期???
故无法实现,即使可行也不现实。


HotWC3单向散列函数就是基于碰撞实现的,某个散列值对应巨多的原文信息。
即多对一的问题,就是日期和星期的关系。无法查表。


而且原文信息变长,这是散列函数的特性。
任意长度的原文信息都会经过散列函数被散列为固定长度的散列值。
从一个方向运算很容易,而从另一个方向运算很难。
故只有知道了用户密码才很容易计算出散列值,反之从散列值还原出用户密码几乎不可能实现。因为碰撞很多,而只有一个是对的。


菜农的CRC安全密码就是基于碰撞实现的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会针对你的问题进行回答。 首先,根据你的要求,我们需要设计一个哈希表来存储30个人的姓名,且平均查找长度的上限为2。为了实现这个目标,我们可以采用除留余法构造哈希函,用线性探测再散列法处理冲突。 具体步骤如下: 1. 首先确定哈希表的大小,由于我们只需要存储30个人的姓名,可以选择哈希表的大小为31,因为31是一个质,有利于减少冲突的发生。 2. 然后根据哈希函,将每个人的姓名映射到哈希表中的一个位置上。假设我们使用汉语拼音表示每个人的姓名,那么可以将每个姓名的首字母的ASCII码值相加,然后取余得到该姓名在哈希表中的位置。具体公式如下: ``` hash(key) = (key[0] + key[1] + ... + key[n-1]) % 31 ``` 其中,`key`表示每个人的姓名。 3. 如果发生冲突,即两个人的姓名映射到了同一个位置上,我们可以使用线性探测再散列法来解决。具体的做法是,从发生冲突的位置开始,依次向后查找,直到找到一个空闲位置或者查找了整个哈希表。如果找到了空闲位置,就将该姓名存储在该位置上;否则,就重新计算哈希值,继续查找下一个位置,直到找到一个空闲位置为止。 4. 最后,为了保证平均查找长度的上限为2,我们需要控制哈希表的装载因子。装载因子是指已经存储据占哈希表总大小的比例。通常情况下,装载因子不宜超过0.7,否则会导致冲突的频率过高,影响查找效率。因此,在本例中,我们可以设置哈希表的最大容量为43(31/0.7),当哈希表中已经存储了43个人的姓名时,就需要重新构建一个更大的哈希表来存储据。 完成建表后,我们可以输入人名进行查找。具体操作如下: 1. 输入要查找的人名,将其转换为哈希表中的位置。 2. 如果该位置上存储的姓名与要查找的姓名相同,说明查找成功,输出该人名、关键字、存储位置及平均查找长度等信息。 3. 如果该位置上存储的姓名与要查找的姓名不同,说明发生了冲突,需要继续向后查找,直到找到空闲位置或者查找了整个哈希表。 4. 如果找到空闲位置,说明要查找的人名不存在,给出对应提示。 5. 如果查找了整个哈希表,仍然没有找到要查找的人名,也给出对应提示。 最后,为了方便查看哈希表中的存储情况,可以编写一个显示哈希表的函,将哈希表中每个位置上存储据都输出到屏幕上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值