02 | 余数:原来取余操作本身就是个哈希函数
黄申
该思维导图由 AI 生成,仅供参考
你好,我是黄申。今天我们来聊聊“余数”。
提起余数,我想你肯定不陌生,因为我们生活中就有很多很多与余数相关的例子。
比如说,今天是星期三,你想知道 50 天之后是星期几,那你可以这样算,拿 50 除以 7(因为一个星期有 7 天),然后余 1,最后在今天的基础上加一天,这样你就能知道 50 天之后是星期四了。
再比如,我们做 Web 编程的时候,经常要用到分页的概念。如果你要展示 1123 条数据,每页 10 条,那该怎么计算总共的页数呢?我想你肯定是拿 1123 除以 10,最后得到商是 112,余数是 3,所以你的总页数就是 112+1=113,而最后的余数就是多出来,凑不够一页的数据。
看完这几个例子,不知道你有没有发现,余数总是在一个固定的范围内。
比如你拿任何一个整数除以 7,那得到的余数肯定是在 0~6 之间的某一个数。所以当我们知道 1900 年的 1 月 1 日是星期一,那便可以知道这一天之后的第 1 万天、10 万天是星期几,是不是很神奇?
你知道,整数是没有边界的,它可能是正无穷,也可能是负无穷。但是余数却可以通过某一种关系,让整数处于一个确定的边界内。我想这也是人类发明星期或者礼拜的初衷吧,任你时光变迁,我都是以 7 天为一个周期,“周”而复始地过着确定的生活。因为从星期的角度看,不管你是哪一天,都会落到星期一到星期日的某一天里。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
哈希函数与余数的关系 余数运算本身就是一种哈希函数,通过余数将整数进行分类。哈希函数将任意长度的输入压缩为固定长度的输出,类似于求余过程。利用余数和同余定理设计散列函数和哈希表结构,实现数据存储和快速读写。引入随机数可以增加数据散列的随机程度,适用于加密算法和数据分发。本文介绍了哈希函数的原理和应用,以及利用余数和同余定理设计散列函数的方法。余数的应用不仅限于数学领域,还涉及到编程中的散列函数、加密算法以及循环冗余校验等方面。通过理解余数的思想,读者可以发现数学思想在编程和生活中的实用性,为编程和生活带来意想不到的作用。欢迎读者思考在生活和编程中还有哪些地方用到了余数的思想,并分享学习笔记。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《程序员的数学基础课》,新⼈⾸单¥68
《程序员的数学基础课》,新⼈⾸单¥68
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(184)
- 最新
- 精选
- Only now尾号限行啊!
作者回复: 这个例子👍
2018-12-122238 - 我来也关于文中的例子有点不解: "假如说,我们要加密数字 625,根据刚才的规则,我们来试试。假设随机数我选择 590127。那百、十和个位分别加上这个随机数,就变成了 590133,590129,590132。然后,三位分别除以 7 求余后得到 5,1,4。最终,我们可以得到加密后的数字就是 415。因为加密的人知道加密的规则、求余所用的除数 7、除法的商、以及所引入的随机数 590127,所以当拿到 415 的时候,加密者就可以算出原始的数据是 625。是不是很有意思?" 正向加密可以理解. 反向解密感觉有点问题呀. -------------- 625中间的数字2: (2 + 590127)%7 = 1. 但是(9 + 590127)%7 = 1 -------------- 那么625和695最终加密后的结果都是415啊. 那就不一定能还原出来原始的值了啊. -------------- 另外,如果最后一位数字加密后的结果是0, 交换位置后, 会有麻烦吧.
作者回复: 这里还要用到除法中的商
2018-12-129118 - 蒋宏伟个人觉得余数用分类来形容有些不恰当,当更恰当的词是均分。分类,每类数量不一定相同,当均分,每类数量是相同的。
作者回复: 确实分类这个词有歧义,常规的取余是均分
2018-12-15570 - ferry同余定理的意义就在于将无限转换为有限,为分类提供了一个标准。比如数字,在没有数字以前,如果我们想表达十以内的数,我们可以用手指或者一些别的工具表示,再后来则是有了代表1-10的阿拉伯数字,那如果要表达一个很大的数,该怎么办呢,我们采用了以十为模的标准,比如十一,对模取余得到1,这样我们可以将任何一个数用1-10来表示,那被模抵消掉的十怎么办呢,我们通过高低位来表示超过十以后的数,每十位就进一,这就解决了表达大数值的方法,从这个角度来看,我们也可以说一个数值就是就是一串余数按照特定顺序的排列。
作者回复: 很好的心得
2019-03-05344 - plasmatium我用余数最多的就是前端动画循环,比如要控制动作循环,数据放一个数组里,假设数组长度是17那么只要arr[i%17];i++; 就行了,不需要那种判断i有没有等于17,等于就置零,否则加一,那样太丑了
作者回复: 是的 :)
2019-02-04434 - Transient在各种进制转换的过程中也需要用到余数。例如:十进制的100转换成二进制,就可以使用循环取余。还有就是在求水仙花数的时候,取十进制上每一位的数值的过程中可以使用取余运算
作者回复: 是的,融汇贯通,赞👍
2018-12-1233 - Lambert可以运用在周易罗盘排盘,十天干和十二地支组成六十甲子,模为60,可以排出现在是哪个布局
作者回复: 这个例子很赞
2019-01-1720 - smarttime老师能不能再深入些,这些太表面化了,另同问加密之后怎么解密的,规则没说3个数字除以7商要相同吧!多讲些实际应用,文章字数有些少!
作者回复: 好的 在后面的文章中我多用一些实例
2018-12-13213 - 羊毛犬 ส็็็็็็@我来也 比如621中的1用 (1+590127) %7 会得到0。 但是如果固定是三位数的话,在解密时候就可以提前给首位补0。 python 版本:(多位数,用反转 代替 对调一三位) ``` # coding:utf-8 DIVIDEND = 7 RAND = 590127 def encrypt(num): if not isinstance(num, int): raise TypeError("num is not 'int' object") # int转为list num = map(int, str(num)) # 对每位加上随机数 num = map(lambda i:i+RAND, num) # 保存商和求余 quotient, num = zip(*[(i//DIVIDEND, i%DIVIDEND) for i in list(num)]) # 反转 num = list(num)[::-1] print(list(num)) # list 转回 int num = map(str, num) # num = int(''.join(list(num))) num = ''.join(list(num)) # 首位余数0则会去除,所以用str # 返回加密数据和商 return (num, quotient) def decrypt(num, quotient): #if not isinstance(num, int): # raise TypeError("num is not 'int' object") # int转为list num = map(int, str(num)) # 反转 num = list(num)[::-1] # 商和余求值 for i,v in enumerate(num): num[i] = v + quotient[i] * DIVIDEND # 对每位减去随机数 num = map(lambda i:i-RAND, num) # list 转回 int num = map(str, num) num = int(''.join(list(num))) return num if __name__ == '__main__': num = 8251 print('加密', num) en_num, q = encrypt(num) print(f"加密后{en_num}, 商为{q} \n解密...") de_num = decrypt(en_num, q) print(de_num) ```
作者回复: 感谢提供这么详尽的代码,另外Web版留言区好像也支持缩进格式了👍
2019-02-14212 - 丁丁历险记上班累了一天,发散发散,但凡产生了精度,也是对应精度数的 余数的适用场景。 他将一段数据内无限个连续数据,reduce 到有限范围内,支撑整个文明的发展。 大家衣服鞋子的码数,真实世界没有尺寸完全相同的一双脚,甚至同一双脚不同时间尺寸不同,同过取余,只用几十个码数,就匹配了xx人数的脚。
作者回复: 很形象的例子,赞👍
2019-10-0911
收起评论