基於米勒-拉賓素性測試 c代碼演示

最近在學密碼學, 老師佈置了個素性檢驗的題目, 然後就是愉快的寫代碼了。 代碼寫的有點雜亂, 而且有幾個地方都可以優化一下。 另外就是用到了大數庫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  代碼地址,歡迎留言交流

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章