中国剩余定理
算法介绍
中国剩余定理(Chinese Remainder Theorem)即孙子定理,是中国古代求解一次同余式组的方法,又称中国余数定理。在《孙子算经》中,“物不知数”的问题下:有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?如果用现代语言描述,可以给出一元线性同余方程组:
\[(S):\begin{cases}
x \equiv a_1 \; (mod \; m_1) \\
x \equiv a_2 \; (mod \; m_2) \\
\cdots \\
x \equiv a_n \; (mod \; m_n)
\end{cases}
\]
假设整数 \(m_1, m_2, \cdots, m_n\) 两两互质,则对任意的整数 \(a_1, a_2, \cdots, a_n\),方程组有解,并且通解可以用如下方式构造得到:
- 设 \(M = \prod_{i=1}^{n} m_i\),是整数 \(m_1, m_2, \cdots ,m_n\) 的乘积,并设 \(M_i = M / m_i\) 是除 \(m_i\) 以外的 \(m\) 个数的乘积
- 设 \(t_i = M_i^{-1}\) 是 \(M_i\) 模 \(m_i\) 的逆元,\(t_i M_i \equiv 1 \; (mod \; m_i)\)
- 方程组 \((S)\) 的通解形式为
\[x = \sum_{i=1}^{n} a_i t_i M_i \; (mod \; M)
\]
需要注意,中国剩余定理的前提条件是模数互素
算法流程图
具体代码(python)
def ex_gcd(a: int, b: int) -> (int, int, int):
"""
:return: gcd x y
"""
if a == 0 and b == 0:
return None
else:
x1, y1, x2, y2 = 1, 0, 0, 1 # 初始化x1,y1,x2,y2
while b:
q, r = divmod(a, b)
a, b = b, r # gcd(a,b)=gcd(b,a%b)
x1, y1, x2, y2 = x2, y2, x1 - q * x2, y1 - q * y2
# 返回一个三元组,依次是(gcd,x,y),使得 xa+yb=gcd
return (a, x1, y1) if a > 0 else (-a, -x1, -y1)
def crt(r_lst: list, m_lst: list):
"""
:param r_lst: 余数列表
:param m_lst: 模数列表
:return: 同余式的解 x
"""
r_lst = [r % m for (r, m) in zip(r_lst, m_lst)] # 预先初始化
M, res = 1, 0
# M = m1*m2*...*mn
for m in m_lst:
M = M * m
for r, m in zip(r_lst, m_lst):
temp = r * M // m * ex_gcd(M // m, m)[1]
res = (res + temp) % M
return res
测试样例及结果
#样例一
r1 = 0
r2 = 0
r3 = 0
m1 = 23
m2 = 28
m3 = 33
# 结果
x = 0
#样例二
r1 = 5
r2 = 20
r3 = 34
m1 = 23
m2 = 28
m3 = 33
# 结果
x = 19900
#样例三
r1 = 283
r2 = 102
r3 = 23
m1 = 23
m2 = 28
m3 = 33
# 结果
x = 9230
# 样例四
r1 = 802310684485241212312289432691586430708135062249
r2 = 961714109955647014172499578071923389425123540027
r3 = 1381194006087304024683552712488022595194097928701
m1 = 489808178709479466279507878773770708214878979673
m2 = 896234965496726578561614071442814700467907036641
m3 = 1213827005758305602466882992172310409456053868843
# 结果
x = 509678885274099350362023393352578082708427568899031846709831030150136786034479833877558685987430752184856829540175601138538702893016912367204417
# 样例五
r1 = 8157969540288411637818433039558323184074779086100165504668538221920170369774913261335059602331627321130656458962980224196880533337839226059601303464776145
r2 = 9699616044315021194953572561076502992783130623216574220426043600142343504101508838526221359049417564415801914072315788919275792502477693022853881785198116
r3 = 7832693802256371667866514213119452199821916193668106904135812283217637737600922381702016472708855675649121271702977408217814917908566132517503707494037556
m1 = 13392316081651420877308875276166772808601812122052371442339078877740399569281672683820206196320955005869072002883847646526584107260355414977120453263391947
m2 = 9734466939658282823343760206593283968765904848250021580218634383869090913086348857668999272399075016287736914000854272239315769632719896968098820774563511
m3 = 9460200357790728398862913232664036038694521858415765931064505193755202156521446156499075450033429983317127589636591133111239548821251790171694322930011927
# 结果
x = 140572312041533061939584609644717750021442788242435867722409828434892657662537831184923189181096394076478262531889424668688702308599804777751973228204825311287964733040400616834339634575632758809487770732820709381703577738588480472947498776340910097209045550068926957348504285471095081384232331643227847899239
用途
中国剩余定理用于求解同余方程组,可以优化算法 RSA 的解密
参考资料:《密码学实验教程》