余数-取余操作就是哈希函数

今天学习的是余数,很常见的知识。

生活中的余数

在生活中有很多用到余数的例子,最常见的一周七天。譬如今天周六,那50天后是周几呢?

答案显而易见,50除以7得商7余数为1,在今天的基础上加1,50天后就是周日。这是日常生活中的例子,而在web编程中,我们有分页的概念,譬如有1234条数据,每页10条,请问需要多少页?1234除以10得商112余数4,那就是112页加上最后4条数据构成的1页,一共113页。

以上两个小例子,我们可以发现余数总是在一个固定的范围内。然而众所周知,整数是没有边界的,可余数却能够通过某一个种关系,让整数处于一个确定的边界。如上面的例子,一周七天让时间确定在了这周一到周日的7天中,假设今天是周一,那第8天、第15天还是周一,这些书除以7得到的余数都是一样的。这样一个现象被归纳总结为同余定理。

同余定理

同余定理,就是两个整数a和b,如果它们除以正整数m得到的余数相等,那就可以说a和b对于模m同余。

同余定理还有一个很常见的应用就是奇偶数,它的模也就是2,一个数除以2得余数为0,表示为偶数;一个数除以2得余数为1,表示为奇数。

同余定理的用途

同余定理可用来分类。对于无穷多的整数,同余定理帮助我们全面、多维度管理这些整数。因为不管模是多少,最终得到的余数肯定在一个确定的范围内。譬如,模为2,余数范围0-1;模为7,余数范围0-6。按照这个方式就能够把无穷多的整数分成有限个类。正是这一点,在计算机中是大有用途的。

哈希函数,将任意长度输入,通过哈希算法,压缩为某一固定长度的输出。这一思路和上面的同余定理如出一辙。

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

举个例子,快速读写100万条数据记录。为达到告高速存取的最理想情况就是开辟一个连续空间存放,这样可减少寻址时间。但实际上无法满足如此大的连续空间来存放数据,这时,我们就可以用之前那个分页的概念。看系统中是否能提供若干个连续空间,每个空间又可以存放一定数量的记录,这些空间加起来就正好满足100万条记录。那么就可以使用余数和同余定理来设计一个散列函数,实现哈希表的结构。

首先,我们可以根据需求列出一个表达式:f(x) = x  mod  size

表达式中 x 表示等待被转换的100万条数据中的1条记录数值,mod 为取余操作,size 表示有限的存储空间大小。通过余数,可以将任何数值转化成有限范围内的数值,然后根据这个新的数值来确定记录应该存放在哪个空间。

假设,有限存储空间大小为100,那么就可以通过记录标号模100的余数指定某条记录存放在哪个空间。譬如有2条记录分别为1和101,它们模100之后的余数为1,让这样的记录存放在我们自定义为1的那个空间中,以此类推,记录2、101和202...余数为2的记录存放在2这个空间里。如此这样我们就能够得到求余的快速数字变化,对数据进行分组存放在不同的地址空间中。

除此之外,如果为了增加数据散列的随机程度,可以将公示转变为 f(x) = (x+MAX)  mod  size,其中MAX是较大的随机数。假设MAX是590199,那么针对标号为1的记录进行重新计算结果为0,标号为101的计算结果变成了2,这就与先前的情况不同了。这是因为加入了随机数MAX使得记录分配到同一空间中的情况更加“随机”,是适合数据重新洗牌的场景。譬如,加密算法。引入随机数可以增强加密算法的保密程度。

举个列子,加密一个三位数,设定这样一个加密规则:

  1. 先对三位数的个十百位的数加上个MAX
  2. 然后将每位上的数除以7,用所得到的余数替换掉原本的数
  3. 最后将百位和个位上的数互换位置

这里我们假设三位数是625,MAX为590127。那么百位上相加结果为590133,十位590129,个位590132,它们除以7得到的余数是百位上5,十位上1,个位上4,互换百位和个位,最终结果就是415。

这就是一个很简单的加密算范,把原本一个数通过加密变完全变个样,只有知道加密规则才可以通过反推得到原本的数。而这里面恰恰最重要的思想就是余数的运用。

猜你喜欢

转载自blog.csdn.net/bertZuo/article/details/85011026