扩展欧几里得算法求逆元

    科技2024-11-02  16

    最近经常会遇到RSA的题目,都会用到扩展欧几里得算法来求逆元,所以去系统的学习了一下这个算法的原理。 先奉上dalao的博客 https://blog.sengxian.com/algorithms/gcd-extgcd

    前置说明

    a | b 表示:a可以整除b

    用途

    扩展欧几里得算法是用来求解方程 a x + b y = c ( a , b , c ∈ Z ) ax + by = c (a,b,c \in Z) ax+by=c(a,b,cZ)

    可解条件

    g c d ( a , b ) ∣ c gcd(a, b) | c gcd(a,b)c

    实现

    记 exgcd(a, b, x, y) 为求解方程 a x + b y = g c d ( a , b ) ax + by = gcd(a,b) ax+by=gcd(a,b) 的函数

    先考虑边界情况: 当b = 0时,有 ax = gcd(a, 0) 解得 { x = 1 y = 0 \left\{\begin{aligned}x&=1\\y&=0\end{aligned}\right. {xy=1=0 对于一般情况,设 a ′ = a a^{'} = a a=a, b ′ = a % b b^{'} = a \% b b=a%b 则有: a ′ x ′ + b ′ y ′ = g c d ( a ′ , b ′ ) = g c d ( b , a % b ) a^{'} x^{'} + b^{'} y^{'}=gcd(a^{'}, b^{'}) =gcd(b, a\%b) ax+by=gcd(a,b)=gcd(b,a%b)

    恒定条件: g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b) = gcd(b, a\%b) gcd(a,b)=gcd(b,a%b)

    又有: g c d ( a , b ) = a x + b y gcd(a, b) = ax+by gcd(a,b)=ax+by 所以有: a x + b y = a ′ x ′ + b ′ y ′ ax+by = a^{'} x^{'} + b^{'} y^{'} ax+by=ax+by a ′ x ′ + b ′ y ′ = b x ′ + ( a % b ) y ′ = b x ′ + ( a − └ a b ┘ b ) y ′ = a y ′ + b ( x ′ − └ a b ┘ y ′ ) a^{'} x^{'} + b^{'} y^{'} = bx^{'}+(a\%b)y^{'}=bx^{'}+(a-\llcorner\frac{a}{b}\lrcorner b)y^{'}=ay^{'}+b(x^{'}-\llcorner\frac{a}{b}\lrcorner y^{'}) ax+by=bx+(a%b)y=bx+(abab)y=ay+b(xbay) a x + b y = a y ′ + b ( x ′ − └ a b ┘ y ′ ) ax+by = ay^{'}+b(x^{'}-\llcorner\frac{a}{b}\lrcorner y^{'}) ax+by=ay+b(xbay) 所以在迭代过程中有: { x = y ′ y = x ′ − └ a b ┘ y ′ \left\{\begin{aligned}x&=y^{'}\\y&=x^{'}-\llcorner\frac{a}{b}\lrcorner y^{'}\end{aligned}\right. xy=y=xbay

    至此扩展欧几里得算法的过程结束,那么这东西跟求逆元有什么关系呢? 对于一个整数x,其逆元 x ′ x^{'} x需要满足: x x ′ ≡ 1 ( % b ) xx^{'} \equiv1(\%b) xx1(%b) 那么一定存在: x x ′ = k b + 1 xx^{'} = kb+1 xx=kb+1 将该方程转化为: a x − k b = 1 ax-kb=1 axkb=1 再令 y = − k y=-k y=k 转化为: a x + b y = 1 ax+by=1 ax+by=1 则该方程的解x即为我们要求的逆元

    def exgcd(a, b): if b == 0: return 1, 0, a x, y, gcd = exgcd(b, a % b) return y, x - a // b * y, gcd def get_inv(a, b): x, y, gcd = exgcd(a, b) if gcd == 1: return (x % b + b) % b else: raise Exception("不存在逆元")
    Processed: 0.016, SQL: 8