我正在尝试实现pollard rho算法来计算大数。我正在使用gmp包。该算法取自“算法简介”。症状是while循环永不中断。我的想法是,我在实施中遗漏了一些东西。
我的代码如下:
#include <iostream>
#include <gmp.h>
#include <stdio.h>
#include <math.h>
#include <gmpxx.h>
using namespace std;
//int numberToFactor;
int compare1;
int compare2;
int factor[100] ;
int k;
int i;
int main (){
mpz_t numberToFactor;
mpz_init(numberToFactor);
mpz_t D;
mpz_init(D);
mpz_t x;
mpz_init(x);
mpz_t y;
mpz_init(y);
mpz_t random;
mpz_init(random);
mpz_t largest;
mpz_init(largest);
mpz_t square;
mpz_init(square);
mpz_t yMinusx;
mpz_init(yMinusx);
unsigned long int exp = 2;
unsigned long int one = 1;
gmp_randstate_t state;
gmp_randinit_mt(state);
while(stdin){
cout<<"enter number";
cin >> numberToFactor;
//Is it a prime number?
int c = mpz_probab_prime_p(numberToFactor, 5);
//Start of Pollard Rho algorithm
i = 1;
//Generate a random number random.
mpz_urandomm(x, state, numberToFactor);
//y = x;
mpz_set(y, x);
cout<<"y="<<y<<"\n";
k = 2;
while(true){
i++;
//square = x².
mpz_pow_ui(square, x, exp);
cout<<"x="<<x<<"\n";
cout<<"x²="<<square<<"\n";
//square = x²-1
mpz_sub_ui(square, square, one);
cout<<"x²-1="<<square<<"\n";
//x= (x²-1)mod numberToFactor
mpz_mod(x, square, numberToFactor);
cout<<"x = x²-1 mod numberToFactor="<<x<<"\n";
//y-x
mpz_sub(yMinusx, y, x);
//abs(y-x)
mpz_abs(yMinusx, yMinusx);
cout<<"y-x="<<yMinusx<<"\n";
//D=gcd(abs(y-x),numberToFactor).
mpz_gcd(D, yMinusx, numberToFactor);
cout<<"gcd(abs(y-x), numberToFactor)="<<D<<"\n";
compare1 = mpz_cmp_ui(D, one);
compare2 = mpz_cmp(D, numberToFactor);
//is D!=1 AND D!=numberToFactor?
if(compare1 != 0 && compare2 != 0){
cout<<"D"<<D<< "\n";
//is D a prime?
if(mpz_probab_prime_p(D, 5) == 2){
//save D?
cout<<"Found one prime divisor!"<<"\n";
cout<<"prime = "<<D<<"\n";
}
//is the remainder a prime?
//numberToFactor = numberTofactor/D
mpz_div(numberToFactor , numberToFactor, D);
if(mpz_probab_prime_p(numberToFactor, 5) == 2){
cout<<"The remainder is a prime!"<<"\n";
cout<<"prime = "<<numberToFactor<<"\n";
}
compare1 = mpz_cmp_ui(numberToFactor, one);
if( 0 == compare1 ){
break;
}
}
if(i == k){
//y = x;
mpz_set(y, x);
k = 2*k;
}
}
cout<<"the task is completed!"<<"\n";
}
代码结束
这是我在终止执行之前在终端中获得的一点。
.
.
.
x=4
x²=16
x²-1=15
x = x²-1 mod numberToFactor=5
y-x=0
gcd(abs(y-x), numberToFactor)=10
x=5
x²=25
x²-1=24
x = x²-1 mod numberToFactor=4
y-x=1
gcd(abs(y-x), numberToFactor)=1
x=4
x²=16
x²-1=15
x = x²-1 mod numberToFactor=5
y-x=0
gcd(abs(y-x), numberToFactor)=10
x=5
x²=25
x²-1=24
x = x²-1 mod numberToFactor=4
y-x=1
gcd(abs(y-x), numberToFactor)=1
x=4
x²=16
x²-1=15
x = x²-1 mod numberToFactor=5
y-x=0
gcd(abs(y-x), numberToFactor)=10
x=5
x²=25
x²-1=24
x = x²-1 mod numberToFactor=4
y-x=1
gcd(abs(y-x), numberToFactor)=1
x=4
x²=16
x²-1=15
x = x²-1 mod numberToFactor=5
y-x=0
gcd(abs(y-x), numberToFactor)=10
x=5
x²=25
x²-1=24
x = x²-1 mod numberToFactor=4
y-x=1
gcd(abs(y-x), numberToFactor)=1
x=4
x²=16
x²-1=15
x = x²-1 mod numberToFactor=5
y-x=0
gcd(abs(y-x), numberToFactor)=10
x=5
x²=25
x²-1=24
x = x²-1 mod numberToFactor=4
y-x=1
gcd(abs(y-x), numberToFactor)=1
x=4
x²=16
x²-1=15
x = x²-1 mod numberToFactor=5
y-x=0
gcd(abs(y-x), numberToFactor)=10
x=5
x²=25
x²-1=24
x = x²-1 mod numberToFactor=4
y-x=1
gcd(abs(y-x), numberToFactor)=1
.
.
.
我很抱歉打印输出看起来如何,我有点匆忙。 我将不胜感激任何帮助。
//海伦
答案 0 :(得分:0)
我不确定这是否是唯一的问题,但您的程序并未计算y
的值。
您使用x = f(x) = x²-1
,因此您还需要计算y = f(f(y)) = y⁴ - 2y²
。
答案 1 :(得分:0)
using System;
using System.Numerics;
namespace Simple_Pollard_Rho_Floyd
{ class Program
{ static void Main()
{ /* Variables ****************************************************************/
BigInteger f, n, x, y;
/* Assign Data **************************************************************/
n = 339850094323758691; // 764567807 * 444499613 (~71 ms)
x = y = 2;
Console.WriteLine("\n\t Simple Pollard Rho Floyd Factoring\n\n {0}", n);
/* Algorithm ****************************************************************/
do
{ x = ((x * x) + 1) % n;
y = ((y * y) + 1) % n; // Floyd
y = ((y * y) + 1) % n;
f = BigInteger.GreatestCommonDivisor(BigInteger.Abs(y - x), n);
} while (f == 1);
/* Output Data **************************************************************/
Console.WriteLine("\n factor = {0}\n", f);
Console.Read();
} // end of Main
} // end Program
} // end namespace