将大奇数整数n分解为相应的素数可能被证明是一项艰巨的任务。蛮力方法可以测试所有小于n的整数,直到找到除数。事实证明,这非常耗时,因为除数本身可能是一个很大的质数。
Pollard p-1算法是找出任何整数素数的更好方法。借助模块化幂运算和GCD的组合帮助,它可以立即计算出所有不同的质因数。
算法
- 给定数字n。
初始化a = 2,i = 2 - 直到返回一个因子,再做
一个<-(a ^ i)mod n
d <-GCD(a-1,n)
如果1返回d
别的
我<-i + 1 - 其他因素d'<-n / d
- 如果d’不是素数
n <-d’
转到1
别的
d和d’是两个主要因素。
在上述算法中,“ a”的幂不断提高,直到获得因子“ d”为n。一旦获得d,另一个因子“ d”为n / d。如果d’不是素数,则对d’重复相同的任务
例子:
Input : 1403
Output : Prime factors of 1403 are 61 23.
Explanation : n = 1403, a = 2, i = 2
1st Iteration:
a = (2^2) mod 1403 = 4
d = GCD(3, 1403) = 1
i = 2 + 1 = 3
2nd Iteration:
a = (4^3) mod 1403 = 64
d = GCD(63, 1403) = 1
i = 3 + 1 = 4
3rd Iteration:
a = (64^4) mod 1403 = 142
d = GCD(141, 1403) = 1
i = 4 + 1 = 5
4th Iteration:
a = (142^5) mod 1403 = 794
d = GCD(793, 1403) = 61
Since 1 < d < n, one factor is 61.
d' = 1403 / 61 = 23.
Input : 2993
Output : Prime factors of 2993 are 41 73.
下面是实现。
# Python code for Pollard p-1
# factorization Method
# importing "math" for
# calculating GCD
import math
# importing "sympy" for
# checking prime
import sympy
# function to generate
# prime factors
def pollard(n):
# defining base
a = 2
# defining exponent
i = 2
# iterate till a prime factor is obtained
while(True):
# recomputing a as required
a = (a**i) % n
# finding gcd of a-1 and n
# using math function
d = math.gcd((a-1), n)
# check if factor obtained
if (d > 1):
#return the factor
return d
break
# else increase exponent by one
# for next round
i += 1
# Driver code
n = 1403
# temporarily storing n
num = n
# list for storing prime factors
ans = []
# iterated till all prime factors
# are obtained
while(True):
# function call
d = pollard(num)
# add obtained factor to list
ans.append(d)
# reduce n
r = int(num/d)
# check for prime using sympy
if(sympy.isprime(r)):
# both prime factors obtained
ans.append(r)
break
# reduced n is not prime, so repeat
else:
num = r
# print the result
print("Prime factors of", n, "are", *ans)
输出:
Prime factors of 1403 are 61 23