python仿射变换求乘法逆元扩展欧几里得
Posted Afololer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python仿射变换求乘法逆元扩展欧几里得相关的知识,希望对你有一定的参考价值。
概念
给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K < N且K * M % N = 1,满足条件的K则为M的逆元
暴力求解法
def get(m,n):
for i in range(1,n-1):
if i*m%n==0:
return i
扩展欧几里得求解法
如果y是n的逆元,则mx+ny =gcd(m,n),那么如何求y呢
已知m,n是互素的,最终状态时
m*1+n*0 = 1
那么一直求上一个状态逆推回去到右边为gcd(m,n)时,求得逆元y
下面分析下从mx+ny =gcd(m,n)推导到m1+n0 = 1
m = kn +余数 m%n = m - kn = m - m//n,得
nx + (m-m//n)*y = gcd(n,m%n),化简为
m*y(上一步的y) + n *(x-(m//n)*y)
正推每一步的下一状态,其中x,y都是上一步的,下一步的m,n 为x , y的系数
而根据欧几里得定理mx+ny =gcd(m,n) = m1+n0 = 1,故可以这样计算
xnext = y
ynext = x - m//n*y
使用递归,结束条件为x = 1,y = 0,反推回来,最终状态的上一状态
xbefore = m//n
ybefore = 1
代码
def EX_GCD(a,b,arr): #扩展欧几里得
if b == 0:
arr[0] = 1
arr[1] = 0
return a
g = EX_GCD(b, a % b, arr)
t = arr[0]
arr[0] = arr[1] #x before = y
arr[1] = t - int(a / b) * arr[1]
return g
测试
arr = [0]*2
EX_GCD(47,30,arr)
print(arr[1])
输出11,因为30*11 = 47 * 7+1
EX_GCD(26,7,arr)
print(arr[1])
尴尬,输出的是-11,需要再规范输出,-11+26=15就是7 mod 26的逆元
7*15 = 26 * 4+1
应用之仿射变换
两个密钥,取值范围为 0 到 25
加密函数f(x) = (k1*m + k0 )mod 26
解密 f − 1 f^-1 f−1(x) =( (f(x)-k0)* k − 1 k^-1 k−1)mod26
如果两个数不互素,乘法逆元不唯一,上述算法可能会出错
素性检测
以上是关于python仿射变换求乘法逆元扩展欧几里得的主要内容,如果未能解决你的问题,请参考以下文章