歐幾里得算法(Euclidean Algorithm)


預備知識(不嚴謹定義)

整除:簡單來說, \(a = nb\), 則有\(b|a\),讀作b整除a

約數(divisor):上面整除的例子里,b就是a的約數,公約數就是多個數的共有約數,如2就是4、6、8的公約數

最大公約數(greast common divisor, 簡稱gcd):顧名思義,公約數里最大的一個,設\(gcd(a,b)=m\),則任取a、b的公約數c,有\(c <= m\),需要注意的是,最大公約數往往是整數,特殊的:

  • \(b|a\), 則\(gcd(a, b)=b\)
  • 任取整數\(n\),有\(gcd(0, n)=n\)

互素(relatively prime):兩個數的最大公約數是1,那么我們就稱這兩個數的互素的

如果我們要求最大公約數,我們先來想一下最簡單的思路。

假設\(a>b\),我們使用暴力求解的方式,從1開始,設置一個變量存儲最大公約數值,每發現一個既能整除a又能整除b的數,將其置為最大公約數,直到遍歷到b為止。粗一看,時間復雜度也並不很高,似乎也是可行的方法。但實際上,在實際的密碼學程序中,需要大量的這類操作,並且操作的數往往是非常大的數,這時,這種方法就顯得十分低效,而歐幾里德方法就是為了能夠高效的求取最大公約數。

歐幾里德算法

首先我們來看,設

\[a = q*b+r \\d = gcd(a, b) \]

那么\(r = a-q*b\),由於\(d|a、d|b\),則有\(d|(a-q*b)=r\),即d也是b和r的最大公約數,此外,又有\(b>r => b=q_1*r+r_1\)以此類推,就得到了我們的歐幾里德算法。

算法描述為:

  1. 將輸入置為\(a>b\)
  2. \(a=q*b+r\)
  3. \(r=0\),則\(gcd(a,b)=b\)
  4. 否則,令\(a := b, b := r\), 注意這里的:=是賦值操作,重復2

建議自己模擬一下,易於理解!

歐幾里德算法的實現

# 加減法的實現對計算機的計算方式更友善
def gcd1(a, b):
    a, b = max(a, b), min(a, b)
    while a != b:
        a, b = max(b, a-b), min(b, a-b)
    return a

def gcd2(a, b):
    a, b = max(a, b), min(a, b)
    while a % b != 0:
        a, b = b, a%b
    return b

實用的歐幾里德算法

上面只是歐幾里德算法的直接實現,效率較低,不能滿足實際環境的需要。

通常的生產代碼中使用的最大公約數算法是一種稱作binary GCD的算法,其算法描述如下,

openssl中使用的BN_gcd便使用了該算法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM