gmh5225 发表于 2015-1-2 18:51

【算法】Pollard_rho大整数分解

本帖最后由 gmh5225 于 2015-1-2 22:23 编辑

用途:分解大整数,为RSA公钥私钥 作基础


Pollard_rho原理:
步骤1:
通过某种方法得到a和b(通常用b=(a*a%n+c)%n) 这里的n是要分解的大整数,a是一个随机数,范围,c是一个随机数,范围   a先备份一个给t。
步骤2:
把b=(a*a%n+c)%n 先备份一个给a ,作迭代用 , 再算d=Gcd(ABS(b-a),n)如果t==b,则返回n本身,退出循环,随机失败,或者 d不是1而且也不是n,那么此时返回的d就是一个公因子,否则循环判断步骤2。


Pollard_rho优化:
因为随机会失败,所以我们每次随机几次后,如果失败,那么 先把b给t,然后扩大随机次数继续判断,这里扩大的次数是你自己定的,一般来讲,定个2倍,这样一直循环,直到 a==b 返回n本身,或者找到公因子。

下面给出代码:

#define ll __int64
ll Pollard_rho(ll n,ll c)
{
      ll a,b,t,d;
      ll i=1,k=2;//这里的k就是优化过程中的随机扩大次数,i是计数器
      //srand(time(0)); 这句别加了 太费时间
      a=rand()%n;
      t=a;//先备份一个,因为a会变化
      while (true)
      {
                ++i;//计数器+1
                b=(mult_mod(a,a,n)+c)%n;
                a=b;//要进行迭代,所以这样做
                if (t==a) return n;//如果a==b那么返回n本身,退出循环
                d=gcd(t>b?t-b:b-t,n); //gcd(abs(a-b),n)
                if (d!=1&&d!=n) return d;// 这个时候d是公因子
                if (i==k)   //扩大随机的次数,这是一个优化
                {
                        t=b;//把b的数值给a ,改变之前的a的数值
                        k+=k;//这里把随机次数扩大2倍
                }
      }
}以上只能返回一个公因子,如果我们想把他的全部公因子都找出来,就需要用递归
递归p和n/p (这里的p是上述函数返回的公因子)   用一个全局数组去保存这些数字
ll AllFactor int count=0//一个数组,一个下标

代码如下:
void Solve(ll n)
{
      if (Miller_Rabin(n)) //如果这个公因子是素数,不可再分,则存入
      {
                Allfactor=n;
                return;
      }
      ll p=n;//先把n备份一个
      while (p==n) //如果失败则会返回n本身,那么继续进入此函数计算
      {
                p=Pollard_rho(n,rand()%(n-1)+1);
      }
      Solve(p);//递归这个 公因子,看他可不可以再拆分
      Solve(n/p);//递归这个n/p,看看n/p可不可以拆分
}这样 Allfactor数组中存的就是拆分的因子了,例如n=16则因子是 2 2 2 2
上面的算法需要Miller_Rabin素数测试函数


520Kelly 发表于 2015-1-2 19:09

膜拜搞大型算法的大大

Scar-疤痕 发表于 2015-1-2 19:33

膜拜楼主,学习了!谢谢

lucious 发表于 2015-1-5 02:08

又是算法呀

惜缘情 发表于 2015-1-5 05:48

算法好东西

xujinwen 发表于 2022-1-8 12:02

谢谢楼主分享
页: [1]
查看完整版本: 【算法】Pollard_rho大整数分解