📜  Pollard p-1算法

📅  最后修改于: 2021-05-04 07:30:17             🧑  作者: Mango

将大奇数整数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