欧拉因式分解法

欧拉因式分解法是一种整数分解方法，重点是用两种方式把要分解的数表示为两数平方和。比如要分解 1000009 {\displaystyle 1000009} ，这个数既能写成 1000 2 + 3 2 {\displaystyle 1000^{2}+3^{2}} ，又能写成 972 2 + 235 2 {\displaystyle 972^{2}+235^{2}} ，那么用欧拉的方法就能分解了： 1000009 = 293 ⋅ 3413 {\displaystyle 1000009=293\cdot 3413} 。 能用两种方式把一个整数表示为两数平方和，或许就能分解这个数，这个想法最早是由梅森提出的。但是直到一百年后，这个想法才得到了广泛应用。当时欧拉用他的方法分解了 1000009 {\displaystyle 1000009} ，这个方法也由此得名。当时人们还认为 1000009 {\displaystyle 1000009} 是質數，但是这个数在主流的素性检测算法中都不是伪質數。 对于因子相差不是特别小的数，欧拉因式分解法比费马的方法更高效。如果能比较容易地找出两种方式把要分解的数表示为两数平方和，那么欧拉的方法可能比试除法高效得多。欧拉取得的进展提高了人们分解整数的效率。20 世纪 10 年代，大因数表已经写到了将近一千万[來源請求]那么大了。将数字表示为两数平方和的方法与在费马因式分解法（英语：Fermat's factorization method）中查找平方差的方法基本相同。 欧拉因式分解法最大的缺点是这样的：要分解的整数，它的质因数分解中，如果有任何一个 4k+3 型的質數是奇数次幂的，那么欧拉的方法就不能分解了。原因是，这样的数字不可能是两数的平方和。4k+1 型的奇合数也经常是两个 4k+3 型質數的积（例如 3053 = 43 × 71），由上面的结论可以知道，对于这类数，欧拉的方法是用不了的。 这个限制，就让欧拉因式分解法不太受计算机因子分解算法的欢迎，毕竟对于一个随机的大数，连能不能用这个方法分解它都很难知道。不过近来，有人尝试把欧拉的方法发展成计算机算法，用于已知确实可以应用欧拉方法的特定数字。 婆罗摩笈多-斐波那契恒等式指出，一个两数平方和，和另一个两数平方和，它们的乘积，是又一个两数平方和。欧拉的方法就依赖于这个定理，把它反了过来：给定 n = a 2 + b 2 = c 2 + d 2 {\displaystyle n=a^{2}+b^{2}=c^{2}+d^{2}} ，那么 n {\displaystyle n} 是两个（可能不一样的）两数平方和的积。 首先移项得到 a 2 − c 2 = d 2 − b 2 {\displaystyle a^{2}-c^{2}=d^{2}-b^{2}} 用平方差公式，对两边分别因式分解，得到 ( a − c ) ( a + c ) = ( d − b ) ( d + b ) {\displaystyle (a-c)(a+c)=(d-b)(d+b)} (1) 现在令 k = gcd ⁡ ( a − c , d − b ) {\displaystyle k=\operatorname {gcd} (a-c,d-b)} ，令 h = gcd ⁡ ( a + c , d + b ) {\displaystyle h=\operatorname {gcd} (a+c,d+b)} ，这样就有 l , m , l ′ , m ′ {\displaystyle l,m,l',m'} 满足 ( a − c ) = k l {\displaystyle (a-c)=kl} , ( d − b ) = k m {\displaystyle (d-b)=km} , gcd ⁡ ( l , m ) = 1 {\displaystyle \operatorname {gcd} (l,m)=1} ( a + c ) = h m ′ {\displaystyle (a+c)=hm'} , ( d + b ) = h l ′ {\displaystyle (d+b)=hl'} , gcd ⁡ ( l ′ , m ′ ) = 1 {\displaystyle \operatorname {gcd} (l',m')=1} 把这些代入式 (1)，得到 k l h m ′ = k m h l ′ {\displaystyle klhm'=kmhl'} 约去 k {\displaystyle k} 和 h {\displaystyle h} ，得到 l m ′ = l ′ m {\displaystyle lm'=l'm} 我们知道 l , m {\displaystyle l,m} 互素， l ′ , m ′ {\displaystyle l',m'} 互素，因此 l = l ′ {\displaystyle l=l'} m = m ′ {\displaystyle m=m'} 因此 ( a − c ) = k l {\displaystyle (a-c)=kl} ( d − b ) = k m {\displaystyle (d-b)=km} ( a + c ) = h m {\displaystyle (a+c)=hm} ( d + b ) = h l {\displaystyle (d+b)=hl} 可以看到 m = gcd ⁡ ( a + c , d − b ) {\displaystyle m=\operatorname {gcd} (a+c,d-b)} 还有 l = gcd ⁡ ( a − c , d + b ) {\displaystyle l=\operatorname {gcd} (a-c,d+b)} 现在应用婆罗摩笈多-斐波那契恒等式，我们就得到了 ( k 2 + h 2 ) ( l 2 + m 2 ) = ( k l + h m ) 2 + ( k m − h l ) 2 = ( ( a − c ) + ( a + c ) ) 2 + ( ( d − b ) − ( d + b ) ) 2 = ( 2 a ) 2 + ( 2 b ) 2 = 4 n . {\displaystyle \left(k^{2}+h^{2}\right)\left(l^{2}+m^{2}\right)=(kl+hm)^{2}+(km-hl)^{2}={\bigl (}(a-c)+(a+c){\bigr )}^{2}+{\bigl (}(d-b)-(d+b){\bigr )}^{2}=(2a)^{2}+(2b)^{2}=4n.} 由于每个因子都是两数平方和，那么 ( k , h ) {\displaystyle (k,h)} 和 ( l , m ) {\displaystyle (l,m)} 之中必有一个数对中两个数都是偶数。不失一般性，假设数对 ( k , h ) {\displaystyle (k,h)} 里两数都是偶数。于是就可以这样分解了： n = ( ( k 2 ) 2 + ( h 2 ) 2 ) ( l 2 + m 2 ) . {\displaystyle n=\left(\left({\tfrac {k}{2}}\right)^{2}+\left({\tfrac {h}{2}}\right)^{2}\right)\left(l^{2}+m^{2}\right).\,} 已知   1000009 = 1000 2 + 3 2 = 972 2 + 235 2 {\displaystyle \ 1000009=1000^{2}+3^{2}=972^{2}+235^{2}} 用上面的方法计算： 于是 1000009 = [ ( 4 2 ) 2 + ( 34 2 ) 2 ] ⋅ [ ( 14 2 ) 2 + ( 116 2 ) 2 ] {\displaystyle 1000009=\left[\left({\frac {4}{2}}\right)^{2}+\left({\frac {34}{2}}\right)^{2}\right]\cdot \left[\left({\frac {14}{2}}\right)^{2}+\left({\frac {116}{2}}\right)^{2}\right]\,} = ( 2 2 + 17 2 ) ⋅ ( 7 2 + 58 2 ) {\displaystyle =\left(2^{2}+17^{2}\right)\cdot \left(7^{2}+58^{2}\right)\,} = ( 4 + 289 ) ⋅ ( 49 + 3364 ) {\displaystyle =(4+289)\cdot (49+3364)\,} = 293 ⋅ 3413 {\displaystyle =293\cdot 3413\,} function Euler_factorize(int n) -> list[int] if is_prime(n) then print("数字是質數，不能分解") exit function for-loop from a=1 to a=ceiling(sqrt(n)) b2 = n - a*a b = floor(sqrt(b2)) if b*b==b2 break loop preserving a,b if a*a+b*b!=n then print("数字无法表示成平方和") exit function for-loop from c=a+1 to c=ceiling(sqrt(n)) d2 = n - c*c d = floor(sqrt(d2)) if d*d==d2 then break loop preserving c,d if c*c+d*d!=n then print("没有第二种表示成平方和的方法") exit function A = c-a, B = c+a C = b-d, D = b+d k = GCD(A,C)//2, h = GCD(B,D)//2 l = GCD(A,D)//2, m = GCD(B,C)//2 factor1 = k*k + h*h factor2 = l*l + m*m return list[ factor1, factor2 ] Ore, Oystein. Euler's Factorization Method. Number Theory and Its History. Courier Corporation. 1988: 59–64. ISBN 978-0-486-65620-5.  McKee, James. Turning Euler's Factoring Method into a Factoring Algorithm. Bulletin of the London Mathematical Society. 1996, 4 (28): 351–355. doi:10.1112/blms/28.4.351.