求离散对数

#include

#define MAX 100

void main()

{   int i,j, num,sum=0, m[MAX]={0},mm[MAX]={0},mm1[MAX]={0},mmm=1,a,n,q,p,b;

int theone(int ,int ,int,int,int);

 int poww(int ,int);

 printf("***********************************************************\n");

 printf("a^cmodp  q(为分解得到的素因子)  n(为素因子的幂)\n");

     printf("测试 p=41 a=6 b=29    求得离散对数c=7\n");

     printf("p=37 a=2 b=29    求得离散对数c=21\n");

 printf("***********************************************************\n");

 

   printf("分成几个素因子,请输入素因子的个数:\n");

   scanf("%d",&num);

   for(i=0;i

   {

printf("b^cmodp;a^cmodp  abp q n输入五个数值 以次是:\n");

    scanf("%d%d%d%d%d",&a,&b,&p,&q,&n);

mm[i]=(p-1)/poww(q,n);

for(j=0;j

if(j*mm[i]%poww(q,n)==1)

mm1[i]=j;

m[i]=theone(a,b,p,q,n);

   }

   for(i=0;i

   {  mmm*=mm[i];

   sum=sum+mm[i]*mm1[i]*m[i];

   }  

   printf("%d\n",sum%mmm);

}

int theone(int a,int bb,int p,int q,int n)//求出每个方程的解

 {

int i=0,j=0,k,k1=0,ani,c,aa[MAX]={0},b[MAX]={0};

           int mod(int,int,int);

   int poww(int ,int);

   b[0]=bb;

           c=(p-1)/q;

if(mod(b[0],c,p)==mod(a,0,p))

{ aa[0]=0;

}else {

            for(i=0;mod(b[0],c,p)!=mod(a,c*i,p);)

{

         i++;

             aa[0]=i;

}

}

     if(n>1)

   {

  for(k=1;k

     if(a*k%p==1)

  ani=k;

      for(j=0;j

  {  

              b[j+1]=b[j]*poww(poww(ani,aa[j]),poww(q,j))%p;

 

          if(mod(b[1+j],c/poww(q,j+1),p)==mod(a,0,p))

  { aa[j+1]=0;

  } else{

                 for(i=0;mod(b[j+1],c/poww(q,j+1),p)!=mod(a,c*i,p);)

 {

             i++;

                    aa[j+1]=i;

 }

 }

  }

   

}

 for(i=0;i

 k1=k1+aa[i]*poww(q,i);

 return(k1);

}

 

     int mod(int x,int r,int n)//模乘法

 {

       int i=0,temp,a[30],first=1;

       for(;i<30;i++)

   {temp=r%2;

       a[i]=temp;

       r=r/2;

       if(r==0)

       break;

   }

       for(;i>=0;i--)

   {

         first=first*first %n;

         if(a[i]==1)

         first=(first*x)%n;

   }

       return(first);

 }

 

    int poww(int x,int y)//指数函数

{

 int i,sum=1;

 if(y==0)

 return(1);

  else{

     for(i=0;i

     sum=sum*x;

     return(sum);

  }

转载于:https://my.oschina.net/u/1754792/blog/229301

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值