最近在学密码学, 老师布置了个素性检验的题目, 然后就是愉快的写代码了。 代码写的有点杂乱, 而且有几个地方都可以优化一下。 另外就是用到了大数库miracle .....
如有问题请提出 。
#include <stdio.h>
#include "miracl.h"
#include "mirdef.h"
#include <time.h>
#define T 11 // T is the number of A
#define PRIME 1
#define COMPISITE 0
big T_A[11];
char *tmp[1000];
int isprime(big);
int T_randnum(big,long long);
int Test_A(big ,int,big,big);
int Ttest_A(big,big,big);
int Find_R_M(big,int,big);
int main()
{
miracl *mips = mirsys(10, 400);
big num = mirvar(0);
printf("Input a number!:");
cinnum(num, stdin);
big num1 = mirvar(1);
if (compare(num, num1) != 1)
{
printf("you can't input number smaller than 2!");
}
long long num_len = numdig(num);
T_randnum(num ,num_len);
int i = isprime(num );
if ( i )
printf("true");
else
printf("wrong");
mirexit();
return 0;
}
int isprime(big num)
{
big M;
int i ,R =0;
M = mirvar(0);
R=Find_R_M(num, R, M);
i = Ttest_A(num,R,M);
if (i == PRIME)
return PRIME;
return COMPISITE;
}
int T_randnum(big N , long long length) //TODO
{
int tmp = 0;
while (1)
{
big x = mirvar(0);
bigrand(N, x) ;
if ( compare(x,N) == -1 )
{
T_A[tmp] = x;
tmp++;
if (tmp == T )
break;
}
}
return 0;
}
int Test_A(big num , int i , int R , big M)
{
big end = mirvar(0);
big zhishu = mirvar(0);
big num1 = mirvar(1);
big w = mirvar(0);
big numsub1 = mirvar(0);
decr(num, 1, numsub1);
powmod(T_A[i], M, num, w);
if (compare(w,num1)==0 )
return COMPISITE;
else
{
for (int x = 0; x < R; x++)
{
big cc = mirvar(0);
big exp2 = mirvar(0);
expb2(x, exp2);
multiply(exp2, M, cc);
powmod(T_A[i], cc,num, end);
if (compare(end, numsub1) == 0)
return PRIME;
}
return COMPISITE;
}
}
int Ttest_A(big num,int R ,big M)
{
for (int i = 0; i < 11; i++)
{
int d = Test_A( num, i,R,M );
if ( d == PRIME)
return 1;
}
return 0 ;
}
int Find_R_M(big num ,int R , big M)
{
// 转化为 二进制
big c = mirvar(0);
big tmp = mirvar(0);
big num2 = mirvar(2);
big end = mirvar(0);
big num0 = mirvar(0);
decr(num, 1, c);
copy(c, tmp);
while (TRUE)
{
divide(tmp, num2, end);
if (compare(tmp, num0) == 0)
R++;
else
break;
copy(end, tmp);
}
int tmpR = 0 - R;
//右移0 个的个数 转为10进制 M
sftbit(num ,tmpR,M);
return R;
}
另附http://download.csdn.net/detail/baidu_28138887/8692079 代码地址,欢迎留言交流