利用miracl库实现Fermat素性检测

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/tch3430493902/article/details/102486153

Fermat素性检测是一种建立在Fermat小定理之上、针对大数的素性检测方案。它虽然能准确地判断“合数”,却无法保证“素数”结论的颠扑不破,换言之,对于“素数”的判断是概率性的。

用到的工具:VS2017、C语言大数库Miracl_5.5.4。

一、Fermat素性检测算法介绍

重要参数:待测大数m(从文件输入),安全参数k(从控制台输入)。
按如下步骤进行检验:

  1. 随机选取整数a,且a大于等于2,小于等于m-2。
  2. 计算a和m的最大公因数g。如果g不等于1(a和m不互素),判断m为合数并退出;否则转到第三步继续判断。
  3. 验证a和m是否满足Fermat小定理的要求。令r=am-1(mod m),若r不等于1,则违背了Fermat小定理,确定m为合数。否则m可能为素数。
  4. 重复k次。若最终m仍可能为素数,则其概率为1-1/(2k

二、miracl环境配置

参考链接:miracl库下载以及配置
前人栽树:很多同学调试时可能会遇到lib库无法正常载入的情况,有可能是文件名后缀的问题,你把cpp改为c后缀试试。
博主在这里栽了两个小时,呜呼哀哉,呜呼哀哉!!!

三、miracl基本函数

参考链接:miracl基本函数介绍
我们要用到的函数mirsys(初始化miracl内存空间)、mirvar(big数初始化)、cinnum(大数的输入)、cotnum(大数的输出)、decr(大数与int数相减)、bigrand(生成随机big数)、egcd(计算两个大数的最大公因数)、compare(比较两个大数的大小)、powmod(计算大数之间的指数次方模值,如am-1(mod m))、mirexit(清理miracl内存空间)。

四、编程实现

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include "miracl.h"

int main()
{
	int k;
	FILE *fp = NULL;
	char fileName[80];
	double probability = 0;
	miracl *mip = mirsys(500,10); //初始化miracl系统
	big m = mirvar(0);
	big a = mirvar(0);
	big g = mirvar(0);
	big r = mirvar(0);
	big temp = mirvar(0);
	big one = mirvar(1);
	
	printf("****************Fermat素性检测算法START******************\n\n");
	//数据初始化:从文件中读取大数,从控制台获取安全参数k
	printf("请输入待检测大数存放的文件名(含路径):");
	scanf("%s", fileName);
	printf("载入大数中..............\n");
	if ((fp = fopen(fileName, "r+")) == NULL) {
		printf("载入大数失败!\n");
		system("pause");
		exit(1);
	}
	cinnum(m, fp);
	printf("载入成功!待检测的大数为:\n");
	cotnum(m, stdout);
	printf("\n现在请输入安全参数k:");
	scanf("%d", &k);
	
	//处理逻辑
	for (int i = 1; i <= k; i++) {
		printf("\n**************Fermat素性检测第%d轮****************\n", i);

		//随机选取整数a
		do {
			decr(m, 1, temp);
			bigrand(temp, a);
		} while (compare(a,one)!=1);
		printf("\n第%d轮生成的随机数a(2=<a=<m-2)为:\n",i);
		cotnum(a, stdout);
		printf("\n");

		//计算g
		egcd(m, a, g);
		printf("第%d轮m和a的最大公因数g为:",i);
		cotnum(g, stdout);
		printf("\n");
		if (compare(g, one)) {
			printf("第%d轮检验失败:a和m不互素,故m为合数\n",i);
			system("pause");
			exit(0);
		}

		//计算r
		powmod(a, temp, m, r);
		printf("第%d轮用于验证Fermat小定理的r为:", i);
		cotnum(r, stdout);
		printf("\n");
		if (compare(r, one)) {
			printf("第%d次检验失败:求解出来的r不等于1,故m为合数\n",i);
			system("pause");
			exit(0);
		}

		//打印结果
		probability = 1 - pow(0.5, i);
		printf("第%d次检验成功:m为素数的概率为:%6.4f\n", i, probability);

	}
	printf("\n****************Fermat素性检测算法END******************\n");
	fclose(fp);
	mirexit();
	system("pause");
	return 0;
}

五、运行效果

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/tch3430493902/article/details/102486153