Bootstrap

如何用计算机算余数,数学余数在计算机的用途

余数

1.余数的特性

整数岁没有边界的,它可能岁正无穷大,也可能是正无穷小,余数却总岁在一个固定的范围内。生活中余数可以用来计算星期,web编程中可以用在分页中。

2.同余定理

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

3.求余过程就是个哈希函数

每个编程语言都有对应的哈希函数。哈希有的时候也会被翻译成散列,简单来说就是将任意长度输入,通过哈希算法压缩为某一固定长度输出。

一个简单的加密规则

先对每个三位数的个、十和百位数,都加上一个较大的随机数。

然后将每位上的数都除以 7,用所得的余数代替原有的个、十、百位数;

最后将第一位和第三位交换。

这就是一个基本的加密变换过程。

产生的问题

"假如说,我们要加密数字 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, 交换位置后, 会有麻烦吧.

解决问题所实现的代码如下

# 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)

其他余数的运用案例

最大公约数和最小公倍数

哈希表

一维转二维

对数字分类

快速查找

加密

迭代时防止溢出

负载均衡

离散存储

周期显示数据的功能(轮播图)

学号

星期

星座

生肖

循环队列

1024游戏

银行卡的位数

周期

计算机内存

推荐图书《密码学 c c++语言实现》

;