欧几里得算法

2017-10-12  本文已影响0人  点点渔火

参考:
https://zh.wikipedia.org/wiki/%E8%BC%BE%E8%BD%89%E7%9B%B8%E9%99%A4%E6%B3%95

序:
欧几里得算法又称辗转相除法, 用来求最大公约数的算法,之前学过,但仅仅是学过公式,并不知道有什么用,最近看RSA的公钥私钥生成原理,发现数学真实神奇,借此机会,深入了解一下。

大的那个数 小的那个数 余数
a b r0 = a%b q0
b r0 r1 = b% r0 q1
r0 r1 r2 = r0 % r1 q2
... ... ... ...
rN-4 rN-3 rN-2 = rN-4 % rN-3 qN-2
rN-3 rN-2 rN-1 = rN-3 % rN-2 qN-1
rN-2 rN-1 rN = rN-2 % rN-1 qN
rN-1 rN == 0 rN-1 = 1 * rN-1 - 0 * rN 0

得到的最大公约数就是rN-1

得证

python 代码:

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)
def ex_gcd(a, b):
    s0 = 1
    t0 = 0
    s1 = 0
    t1 = 1
    m, n = a, b
    while b != 0:
        a, b, q = b, a % b, a // b
        s0, s1 = s1, s0 - q * s1
        t0, t1 = t1, t0 - q * t1
        print "%d = %d * %d + %d * %d" % (a, s0, m, t0, n)
        print "%d = %d * %d + %d * %d" % (b, s1, m, t1, n)
    return s0, t0, a

结果:

30 = 0 * 47 + 1 * 30
17 = 1 * 47 + -1 * 30
17 = 1 * 47 + -1 * 30
13 = -1 * 47 + 2 * 30
13 = -1 * 47 + 2 * 30
4 = 2 * 47 + -3 * 30
4 = 2 * 47 + -3 * 30
1 = -7 * 47 + 11 * 30
1 = -7 * 47 + 11 * 30
0 = 30 * 47 + -47 * 30
(-7, 11, 1)

维基上的算法:
https://zh.wikipedia.org/wiki/%E6%89%A9%E5%B1%95%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%97%E7%AE%97%E6%B3%95
这个明显比我自己推导写的代码要简洁多了,这个代码思想和上面的递推公式是反的, 是从先找到最大公约数, 有等式 g = 1 * s N-1 + 0 * sN开始往回推, 而上面的逻辑是从a, b开始顺序推,一边找最大公约数, 一边解二元一次方程:
逆推公式:
sN = 1, tN = 0
g = 1 * r N-1 + 0 * rN = sN * r N-1 + tN * rN
rN = 1 * rN-2 - qN * rN- 1 = sN-1* rN-2 +tN-1 * rN- 1
有 g = (1 - qN) * r N-1 + 1* rN-2 = (sN - )
rN-1 = 1 * rN-3 - qN-1 * rN- 2
对应的s,t :
sN = 1, tN = 0
sN-1 = 1,

sk - 2 = sk + qk * sk-1
tk - 2 = tk + qk * tk-1

s-2 = 1
s-1 = t -2 = 0
s0 = s-2 - qk * s-1 = s-2 - qk * t -2
不妨设t -3 = 1
上面的式子变为:
s0 = t -3 - qk * t -2 = t -1 = 1
利用数据归纳法可以证明

上一篇 下一篇

猜你喜欢

热点阅读