密码学 欧几里得算法

2020-07-30 16:42 更新

Euclidean欧几里德算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b) = gcd(b,a mod b)。

简介

欧几里德算法是用来求两个正整数最大公约数的算法。古希腊数学家欧几里德在其著作《The Elements》中最早描述了这种算法,所以被命名为欧几里德算法。 扩展欧几里德算法可用于RSA加密等领域。 假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里德算法,是这样进行的: 1997 / 615 = 3 (余 152) 615 / 152 = 4(余7) 152 / 7 = 21(余5) 7 / 5 = 1 (余2) 5 / 2 = 2 (余1) 2 / 1 = 2 (余0) 至此,最大公约数为1 以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数 1。

算法

代码实现

  1. /*
  2. 欧几里德算法:辗转求余
  3. 原理: gcd(a,b)=gcd(b,a mod b)
  4. 当b为0时,两数的最大公约数即为a
  5. getchar()会接受前一个scanf的回车符
  6. */
  7. #include<stdio.h>
  8. unsigned int Gcd(unsigned int M,unsigned int N)
  9. {
  10. unsigned int Rem;
  11. while(N > 0)
  12. {
  13. Rem = M % N;
  14. M = N;
  15. N = Rem;
  16. }
  17. return M;
  18. }
  19. int main(void)
  20. {
  21. int a,b;
  22. scanf("%d %d",&a,&b);
  23. printf("the greatest common factor of %d and %d is ",a,b);
  24. printf("%d\n",Gcd(a,b));
  25. return 0;
  26. }

算法拓展

基本算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。

证明:设 a>b。

  1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;

  2,ab!=0 时

  设 ax1+by1=gcd(a,b);

  bx2+(a mod b)y2=gcd(b,a mod b);

  根据朴素的欧几里德原理有 gcd(a,b)=gcd(b,a mod b);

  则:ax1+by1=bx2+(a mod b)y2;

  即:ax1+by1=bx2+(a-(a/b)b)y2=ay2+bx2-(a/b)by2;

  根据恒等定理得:x1=y2; y1=x2-(a/b)*y2; 这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.

  上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。 扩展欧几里德算法不但能计算(a,b)的最大公约数,而且能计算a模b及b模a的乘法逆元,用C语言描述如下:

  1. #include <stdio.h>
  2. unsigned int gcdExtended( int a, int b, int *x, int *y);
  3. int main(void) {
  4. int a, b,GCD;
  5. int x, y;
  6. a = 1232, b = 573;
  7. /*
  8. gcdExtended(1232, 573)时, x = 20 and y = –43
  9. 1232x + 573y = 1
  10. 24640-24639 = 1
  11. 或者gcdExtended( 573,1232) 时,x=-43, y=20
  12. 573x+1232y = 1
  13. -43*573+1232*20 = -24639+57640 = 1
  14. gcdExtended(9151, 5787) 时
  15. x=2011, y=-3180
  16. */
  17. GCD = gcdExtended(a, b,&x, &y);
  18. printf("gcdExtended(%d, %d) = %d, x=%d, y=%d\n", a, b, GCD,x,y);
  19. return 0;
  20. }
  21. // 欧几里得扩展算法的C语言实现
  22. // ax+by=1
  23. unsigned int gcdExtended(int a, int b, int *x, int *y){
  24. if (a == 0){
  25. *x = 0;
  26. *y = 1;
  27. return b;
  28. }
  29. int x1, y1;
  30. int gcd = gcdExtended(b%a, a, &x1, &y1);
  31. *x = y1 - (b/a) * x1;
  32. *y = x1;
  33. return gcd;
  34. }
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号