Pollard Rho 实施有什么问题

发布于 2024-11-08 03:05:47 字数 849 浏览 0 评论 0原文

#include <iostream>
#include <cstdlib>
typedef  unsigned long long int ULL;
ULL gcd(ULL a, ULL b)
{
   for(; b >0 ;)
   {
       ULL rem = a % b;
       a = b;
       b = rem;
   }
   return a;
}
void pollard_rho(ULL n)
{
   ULL i = 0,y,k,d;
   ULL *x = new ULL[2*n];
   x[0] = rand() % n;
   y = x[0];
   k = 2;
   while(1){
       i = i+1;
       std::cout << x[i-1];
       x[i] = (x[i-1]*x[i-1]-1)%n;
       d = gcd(abs(y - x[i]),n);
       if(d!= 1 && d!=n)
          std::cout <<d<<std::endl;
       if(i+1==k){
         y = x[i];
         k = 2*k;
       }
   }
}

int main()
{
   srand(time(NULL));
   pollard_rho(10);

}

该实现源自 CLRS 第二版(页码 894)。 while(1) 对我来说看起来很可疑。 while 循环的终止条件应该是什么?

我尝试了 k<=n 但这似乎不起作用。我遇到分段错误。代码中有什么缺陷以及如何纠正它?

#include <iostream>
#include <cstdlib>
typedef  unsigned long long int ULL;
ULL gcd(ULL a, ULL b)
{
   for(; b >0 ;)
   {
       ULL rem = a % b;
       a = b;
       b = rem;
   }
   return a;
}
void pollard_rho(ULL n)
{
   ULL i = 0,y,k,d;
   ULL *x = new ULL[2*n];
   x[0] = rand() % n;
   y = x[0];
   k = 2;
   while(1){
       i = i+1;
       std::cout << x[i-1];
       x[i] = (x[i-1]*x[i-1]-1)%n;
       d = gcd(abs(y - x[i]),n);
       if(d!= 1 && d!=n)
          std::cout <<d<<std::endl;
       if(i+1==k){
         y = x[i];
         k = 2*k;
       }
   }
}

int main()
{
   srand(time(NULL));
   pollard_rho(10);

}

This implementation is derived from CLRS 2nd edition (Page number 894). while(1) looks suspicious to me. What should be the termination condition for the while loop?

I tried k<=n but that doesn't seem to work. I get segmentation fault. What is the flaw in the code and how to correct it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

那片花海 2024-11-15 03:05:47

我只有 CLRS 第一版,但假设它与第二版没有太大不同,终止条件的答案在下一页:

这个寻找因子的过程乍一看可能有些神秘。但请注意,POLLARD-RHO 永远不会打印错误的答案;它打印的任何数字都是 n 的非平凡除数。不过,POLLARD-RHO 可能根本不会打印任何内容;无法保证它会产生任何结果。然而,我们将看到,有充分的理由期望 POLLARD-RHO 在大约 sqrt(p ) while 循环的迭代。因此,如果n是合数,我们可以期望这个过程在大约n1/4之后发现足够的除数来完全分解n 更新,因为 n 的每个质因数 p(可能除了最大的一个)都小于 sqrt(n)。

因此,从技术上讲,CLRS 中的演示文稿没有终止条件(这可能就是为什么他们称其为“启发式”和“过程”而不是“算法”),并且不能保证它实际上会产生任何内容有用。实际上,您可能希望根据预期的 n1/4 更新设置一些迭代限制。

I only have a 1st edition of CLRS, but assuming it's not too different from the 2nd ed., the answer to the termination condition is on the next page:

This procedure for finding a factor may seem somewhat mysterious at first. Note, however, that POLLARD-RHO never prints an incorrect answer; any number it prints is a nontrivial divisor of n. POLLARD-RHO may not print anything at all, though; there is no guarantee that it will produce any results. We shall see, however, that there is good reason to expect POLLARD-RHO to print a factor of p of n after approximately sqrt(p) iterations of the while loop. Thus, if n is composite, we can expect this procedure to discover enough divisors to factor n completely after approximately n1/4 update, since every prime factor p of n except possibly the largest one is less than sqrt(n).

So, technically speaking, the presentation in CLRS doesn't have a termination condition (that's probably why they call it a "heuristic" and "procedure" rather than an "algorithm") and there are no guarantees that it will ever actually produce anything useful. In practice, you'd likely want to put some iteration bound based on the expected n1/4 updates.

空袭的梦i 2024-11-15 03:05:47

为什么要存储所有这些中间值?您确实不需要将 x 和 y 放入数组中。只需使用您不断重复使用的 2 个变量:xy

另外,将 while(1) 替换为 while(d == 1) 并在之前切断循环。

 if(d!= 1 && d!=n)
      std::cout <<d<<std::endl;
   if(i+1==k){
     y = x[i];
     k = 2*k;

您的循环应该成为

while(d == 1)
{
    x = (x*x - 1) % n;
    y = (y*y - 1) % n;
    y = (y*y - 1) % n;
    d = abs(gcd(y-x,n))%n;
}
if(d!=n)
  std::cout <<d<<std::endl;
else
  std::cout<<"Can't find result with this function \n";

因此,如果您传递循环内使用的函数, 额外的分数作为 pollard 的参数,这样如果它无法用一个函数找到结果,它就会尝试另一个函数。

Why store all those intermediary values? You really don't need to put x and y in a array. Just use 2 variables which you keep reusing, x and y.

Also, replace while(1) with while(d == 1) and cut the loop before

 if(d!= 1 && d!=n)
      std::cout <<d<<std::endl;
   if(i+1==k){
     y = x[i];
     k = 2*k;

So your loop should become

while(d == 1)
{
    x = (x*x - 1) % n;
    y = (y*y - 1) % n;
    y = (y*y - 1) % n;
    d = abs(gcd(y-x,n))%n;
}
if(d!=n)
  std::cout <<d<<std::endl;
else
  std::cout<<"Can't find result with this function \n";

Extra points if you pass the function used inside the loop as a parameter to pollard, so that if it can't find the result with one function, it tries another.

只为守护你 2024-11-15 03:05:47

尝试将 while(1) { i = i + 1; 替换为:

for (i = 1; i < 2*n; ++i) {

Try replacing while(1) { i = i + 1; with this:

for (i = 1; i < 2*n; ++i) {
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文