本文致力于解决如下问题:求解x≡ab(mod m),其中a,b,m都是正整数。
如果b足够小,则可直接用逐次平方法求解,如果你不知道逐次平方法,可以先看这里。所以这里假设b足够大(这不是说是一个64位整数,而是可以上百上千位的一个数),大到逐次平方法也已不足以快速出解。
用素数探路的思想,先假设m是素数,那么要么 a 与 m 互素,要么 m|a。前者可利用费马小定理,令 b = k(m-1) + b′,其中 0<=b′< m-1,则有 ab≡ak(m-1)+b′≡ab′(mod m)。之后可用逐次平方法快速求解。若m|a,结果显然为0。
现在考虑要求 m 可以是任意数的情况。同样,若 a 与 m 互素,由上边我们可联想到欧拉公式,利用欧拉公式求解。令 b = kΦ(m) + b′,其中 0≤b′<Φ(m),则有 ab≡akΦ(m)+b′≡ab′(mod m),之后用逐次平方法快速求解。如果 a与 m不互素,即 gcd(a,m) > 1,这种情况下应该怎么做?
注意到 b 如此大,而模 m 的不同的数最多只有m个,显而易见的,ab一定和某个很小的指数ab′模m同余,如果找到这个小的指数,就可以利用逐次平方法求解。考虑如下序列:
a0, a1, …, am(mod m)
由鸽巢原理可知,必有一个最小的r和一个最小的s,使得ar≡ar+s(mod m),其中r+s≤m。若找到这样的