github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/datastructures/rsa/rsa.go (about)

     1  package rsa
     2  
     3  // 求两个数的最大公约数
     4  // 欧几里 辗转相除法
     5  func greatestCommonDivisor1(a, b int) int {
     6  	// 欧几里的辗转相除法
     7  	if a < b {
     8  		a, b = b, a
     9  	}
    10  	for a%b != 0 {
    11  		a, b = b, a%b
    12  	}
    13  	return b
    14  }
    15  
    16  // 九章算术 更相减损术
    17  func greatestCommonDivisor2(a, b int) int {
    18  	// 两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数。
    19  	// 比如10和25,25减去10的差是15,那么10和25的最大公约数,等同于10和15的最大公约数。
    20  	if a < b {
    21  		a, b = b, a
    22  	}
    23  	for a != b {
    24  		a = a - b
    25  		if a < b {
    26  			a, b = b, a
    27  		}
    28  		a, b = b, a-b
    29  	}
    30  	return b
    31  }
    32  
    33  func greatestCommonDivisor3(a, b int) int {
    34  	// 更相减损术与移位结合
    35  	if a == b {
    36  		return b
    37  	}
    38  	if a < b { // 保证a >= b
    39  		a, b = b, a
    40  	}
    41  
    42  	if a&1 != 0 && b&1 != 0 {
    43  		//当a和b均为奇数,利用更相减损术运算一次,gcb(a,b) = gcb(b, a-b), 此时a-b必然是偶数,又可以继续进行移位运算
    44  		return greatestCommonDivisor3(b, a-b)
    45  	} else if a&1 == 0 && b&1 == 0 {
    46  		// 当a和b均为偶数,gcb(a,b) = 2*gcb(a/2, b/2) = 2*gcb(a>>1, b>>1)
    47  		return 2 * greatestCommonDivisor3(a>>1, b>>1)
    48  	} else if a&1 == 0 && b&1 != 0 {
    49  		// 当a为偶数,b为奇数,gcb(a,b) = gcb(a/2, b) = gcb(a>>1, b)
    50  		return greatestCommonDivisor3(a>>1, b)
    51  	} else {
    52  		// 当a为奇数,b为偶数,gcb(a,b) = gcb(a, b/2) = gcb(a, b>>1)
    53  		return greatestCommonDivisor3(a, b>>1)
    54  	}
    55  }