JAVA实现辗转相除法 欧几里得算法求逆

乘法逆元定义:

 

一般来讲,如果要运算加法、减法、乘法、乘方,都应该满足以下式子:

 

(a+b)%c=(a%c+b%c)%c(a+b)%c=(a%c+b%c)%c

(a−b)%c=(a%c−b%c)%c(a−b)%c=(a%c−b%c)%c

(a⋅b)%c=(a%c⋅b%c)%c(a·b)%c=(a%c·b%c)%c

ab%p=(a%p)b%pab%p=(a%p)b%p

 

然而这里出现了一个问题:

 

如果是除法,并不满足(a/b)%c=(a%c/b%c)%c(a/b)%c=(a%c/b%c)%c,不信你代个数试试:

 

(6/3)%3=2≠(6%3/3%3)%3=RuntimeError(6/3)%3=2≠(6%3/3%3)%3=RuntimeError

 

那怎么实现对除法的取余呢?

 

这里就引入乘法逆元这个东西。

 

他可以达到这样的效果:

 

(a/b)%k=(a⋅c)%k(a/b)%k=(a·c)%k

 

你可以将它简单地理解为类似于倒数的东西,只不过是再对倒数取余而已,即:

 

(b⋅c)%k=1(b·c)%k=1

 

所以注意,逆元是针对一个数而言的,并不是针对一个表达式。

 

求法

使用扩展欧几里德算法,但是好像只能在所求的数和取余的数互质才行。

 

因为:

 

(b⋅c)%k=1(b·c)%k=1

 

所以我们可以得到

 

b⋅c+n⋅k=1b·c+n·k=1

 

所以只有在bb和kk互质的情况下,才能得到:

 

b⋅c+n⋅k=gcd(b,k)b·c+n·k=gcd(b,k)

 

然后用这个方程求解出cc的值,就是所求的乘法逆元。

 

 

求79关于3220的乘法逆元:

 

运行结果:

 

JAVA实现辗转相除法 欧几里得算法求逆_第1张图片

 

 

 

 

 

附录:

java实现:

 

package oujilide;

 

public class ojld {

 

         public static int  niyuan(int a,int b//79关于模3220的乘法逆元 

         {

                   int[] m={1,0,a};

                   int[] n={0,1,b};

                   int[] temp=new int[3];

                   int q=0;  //初始化

                   boolean flag=true;

                   while(flag)

                   {

                            q=m[2]/n[2];

                            for(int i=0;i<3;i++)

                            {

                                     temp[i]=m[i]-q*n[i];

                                     m[i]=n[i];

                                     n[i]=temp[i];

                                     System.out.print(temp[i]+"   ");

                            }

                            System.out.println();

                            if(n[2]==1)

                            {

                                     if(n[1]<0)

                                               n[1]=n[1]+a;

                                     return n[1];

                            }

                            if(n[2]==0)

                                     flag=false;

                   }

                   return 0;

         }

 

         public static void main(String[] args) {

                   int result = niyuan(3220,79);

                   System.out.println();

                   System.out.println("79关于3220的逆元为:"+result);

         }

}

你可能感兴趣的:(密码学相关算法)