素性测试的Miller-Rabin算法完全解析 (C语言实现、Python实现)

因为文中存在公式,只能用图片方式上传了!

 

以下为C语言源代码:

#include <stdio.h>
typedef long long unsigned LLU;
typedef int BOOL;
#define TRUE 1
#define FALSE 0

BOOL isPrime(LLU n) {  //这是传统的方法,用于与Miller-Rabin算法的结果进行对比。
    if( (n&1)==0 || n%5==0)
        return FALSE;

    LLU i,bnd;
    bnd=sqrt(n);
    for(i=2; i<=bnd; i++)
        if(n%i==0)
            return FALSE;

    return TRUE;
}

//实现(a*b)%c,用类似快速幂的方式实现。
//将模运算下的乘法用加法实现的思想是时间换空间。
//这可以作为典型的时间换空间的例子。
LLU quickMult(LLU a,LLU b,LLU c){
    LLU result=0;
    while(b>0) {
        if(b&1)
            result=(result+a)%c;
        a=(a+a)%c;
        b>>=1;
    }
    return result;
}

//请注意,计算快速幂时,因为变量的数据类型为long long,是64bits长度的整数。
//a的值不能大于(2的32次方-1)≈4000000000
//否则,计算a*a时会越界,超过64bits整数的表示范围。
//例如a,b,c分别为:7087881096594 10000000000036 10000000000037时,
//正确结果 (a^b)%c=1,但是,在此计算的结果不为1。
//因此,可以改进为用“快速乘”代替*乘法运算符,能更加充分第利用64的long long unsigned型的存储空间。
//这个例子可以作为算法改进从O(n)到O(lg(n))的进步的例子。
LLU quickPower(LLU a,LLU b,LLU c) {
    LLU result=1;
    while(b>0) {
        if(b&1)
            //result=result*a%c; //此为直接乘法
            result=quickMult(result,a,c);
        //a=a*a%c; //此为直接乘法
        a=quickMult(a,a,c);
        b>>=1;
    }
    return result;
}

//如果返回值为TRUE表示n为素数,返回值为FALSE表示n为合数。
BOOL MillerRabinPrimeTest(LLU n) {
    LLU d,x,newX,a=1;
    int i;
    for (i=0; i<4; i++)
        a*=rand();
    a=a%(n-3)+2;//随机第选取一个a∈[2,n-2]
    //printf("随机选取的a=%lld\n",a);
    int s=0;//s为d中的因子2的幂次数。
    d=n-1;  //d取初值n-1
    while( (d&1)==0) {//将d中因子2全部提取出来。
        s++;
        d>>=1;
    }

    x=quickPower(a,d,n);
    for(i=0; i<s; i++) { //进行s次二次探测
        newX=quickPower(x,2,n);
        if(newX==1 && x!=1 && x!=n-1)
            return FALSE; //用二次定理的逆否命题,此时n确定为合数。
        x=newX;
    }
    if(x!=1)
        return FALSE;   //用费马小定理的逆否命题判断,此时x=a^(n-1) (mod n),那么n确定为合数。

    return TRUE; //用费马小定理的逆命题判断。能经受住考验至此的数,大概率为素数。
}

//经过连续特定次数的Miller-Rabin测试后,
//如果返回值为TRUE表示n为素数,返回值为FALSE表示n为合数。
BOOL isPrimeByMR(LLU n) {
    if((n&1)==0 || n%5==0)
        return FALSE;
    int i;
    for (i=0; i<100; i++)
        if(MillerRabinPrimeTest(n)==FALSE)
            return FALSE;
    return TRUE;
}

//对比传统方法和Miller-Rabin算法的结果
void check(LLU n) {
    char isRight;
    BOOL resultA,resultB;
    resultA=isPrime(n);
    resultB=isPrimeByMR(n);
    if(resultA==resultB) {
        isRight='V';
        printf("%c,%llu %d %d\n",isRight,n,resultA,resultB);
    } else {
        isRight='X';
        printf("%c,%llu %d %d\n",isRight,n,resultA,resultB);
    }
}

//测试任务:在本人笔记本电脑上测试,N=10的18次方至N+10之间的质数为:
//1000000000000000003
//1000000000000000009
//Miller-Rabin算法的速度:0.22秒
//常规算法:22秒
int main() {    
    srand(time(NULL));

    LLU i,n,N;
    N=1000000000000000000;
    BOOL result;
    for(i=N; i<N+10; i++) {
        n=i;
        //check(n);        
        //result=isPrime(n);
        result=isPrimeByMR(n);
        if(result==TRUE)
            printf("%llu\n",n);

    }
    return 0;
}

 

以下为Python语言源代码:

import math
import randomdef isPrime(n): #这是传统的方法,用于与Miller-Rabin算法的结果进行对比。if (n & 1) == 0 or n % 5 == 0:return Falsebnd = int(math.sqrt(n))for i in range(2, bnd + 1):if n % i == 0:return Falsereturn True# 实现(a*b)%c,用类似快速幂的方式实现。
# 将模运算下的乘法用加法实现的思想是时间换空间。
# 这可以作为典型的时间换空间的例子。
def quickMult(a, b, c):result = 0while b > 0:if b & 1:result = (result + a) % ca = (a + a) % cb >>= 1return result#因为Python支持大整数运算,所以在此也可以不用快速乘法,而直接使用乘法*。
def quickPower(a, b, c):result = 1while b > 0:if (b & 1):# result=result*a%c #此为直接乘法result = quickMult(result, a, c)# a=a*a%c #此为直接乘法a = quickMult(a, a, c)b >>= 1return result#如果返回值为TRUE表示n为素数,返回值为FALSE表示n为合数。
def MillerRabinPrimeTest(n):a = random.randint(2,n-2) #随机第选取一个a∈[2,n-2]# print("随机选取的a=%lld\n"%a)s = 0 #s为d中的因子2的幂次数。d = n - 1while (d & 1) == 0: #将d中因子2全部提取出来。s += 1d >>= 1x = quickPower(a, d, n)for i in range(s): #进行s次二次探测newX = quickPower(x, 2, n)if newX == 1 and x != 1 and x != n - 1:return False #用二次定理的逆否命题,此时n确定为合数。x = newXif x != 1:  # 用费马小定理的逆否命题判断,此时x=a^(n-1) (mod n),那么n确定为合数。return Falsereturn True  # 用费马小定理的逆命题判断。能经受住考验至此的数,大概率为素数。# 经过连续特定次数的Miller-Rabin测试后,
# 如果返回值为TRUE表示n为素数,返回值为FALSE表示n为合数。
def isPrimeByMR(n):if ((n & 1) == 0 or n % 5 == 0):return Falsefor i in range(100):if MillerRabinPrimeTest(n) == False:return Falsereturn True#对比传统方法和Miller-Rabin算法的结果
def check(n):resultA = isPrime(n)resultB = isPrimeByMR(n)if resultA == resultB:isRight = 'V'print("%c,%u %d %d" % (isRight, n, resultA, resultB))else:isRight = 'X'print("%c,%u %d %d" % (isRight, n, resultA, resultB))# 测试任务:在本人笔记本电脑上测试,N=10的18次方至N+10之间的质数为:
# 1000000000000000003
# 1000000000000000009
# Miller-Rabin算法的速度:0.22秒
# 常规算法:22秒
# python的常规算法,耗时更长。
def main():# freopen("result.txt","w",stdout)random.seed()# res=quickPower(2,10,7)# print("%u"%res)N = 1000000000000000000for i in range(N, N + 10):n = i#check(n)# n=int(input())#result=isPrime(n)result = isPrimeByMR(n)if result == True :print("%u" % n)return 0# print(isPrime(1000000000000000003))
# a, b, c = [int(e) for e in input().split(" ")]
# print(quickPower(a,b,c))
# # 7087881096594 10000000000036 10000000000037 =1
main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/262370.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MongoDB源码阅读之ReplSet源码分析

1. ReplSet源码结构 rs_config.h replSet间同步设置的工具类 rs_member.h 心跳检测类和replSet成员状态的定义 rs_sync.h 同步数据类 rs.h 定义了几乎所有replSet相关的类&#xff08;Member:replSet中的节点成员&#xff0c; GhostSync&#xff1a;备份同步类&#xff0c;Rep…

C# 字符串性能

Written By Dr Herbie [2] Translated By Allen Lee Introduction 你在代码中处理字符串的方法可能会对性能产生令人吃惊的影响。程序中需要考虑两个由于使用字符串而产生的问题&#xff1a;临时字符串变量的使用和字符串连接。Background1.String是引用类型&#xff0c;在堆上…

手把手教你部署VSAN见证虚拟设备 (Cormac)

译者注&#xff1a;本文翻译自Cormac的博客&#xff0c;并未严格地逐字逐句的直译&#xff0c;如有谬误&#xff0c;万望见谅。原文见此http://cormachogan.com/2015/09/14/step-by-step-deployment-of-the-vsan-witness-appliance/现在开始在之前的帖子中我曾经介绍过见证虚拟…

mysql在哪儿查看表的代码_查看mysql数据库及表编码格式

转载来源&#xff1a;http://www.cnblogs.com/shootercheng/p/5836657.html一、查看MySQL数据库服务器和数据库MySQL字符集。二、查看MySQL数据表(table)的MySQL字符集。三、查看MySQL数据列(column)的MySQL字符集。1.查看数据库编码格式2.查看数据表的编码格式3.创建数据库时指…

PyCharm编程环境的中英文字体分别设置的好处多----一石三鸟地解决中文字体不一致、英文字体不涵盖中文字符、编程字体实用性兼顾美观性的三个问题

在编程环境&#xff08;例如Python的PyCharm&#xff09;中&#xff0c;我们希望编程环境的字体具有如下特性&#xff1a; &#xff08;1&#xff09;字体覆盖中文和英文字符。 &#xff08;2&#xff09;等宽字体&#xff0c;并且是TrueType字体&#xff0c;方便辨识代码中缩…

WordPress博客系统的安全

随着计算机网络的流行&#xff0c;越来越多的人开始创建自己的博客&#xff0c;论起博客系统&#xff0c;全球用的最多的博客系统就是wordpress&#xff08;以下简称WP&#xff09;。但是如果用过WP的人都应该知道&#xff0c;WP的站点想要做的好看&#xff0c;插件是必不可少的…

C/C++ 程序设计员应聘常见面试试题深入剖析

1.引言 本文的写作目的并不在于提供C/C程序员求职面试指导&#xff0c;而旨在从技术上分析面试题的内涵。文中的大多数面试题来自各大论坛&#xff0c;部分试题解答也参考了网友的意见。许多面试题看似简单&#xff0c;却需要深厚的基本功才能给出完美的解答。企业要求面试者写…

mysql为什么行数据库_关系数据表中的行称为什么?

在一个二维表中&#xff0c;水平方向的行称为元组&#xff0c;每一行是一个元组&#xff1b;元组对应表中的一个具体记录。数据元组也称为记录。一个数据表中的每一个记录均有一个惟一的编号(记录号)。一个记录也就是数据表中的一行。元组(tuple)是关系数据库中的基本概念&…

长截图或长图片如何按页面切分后打印或插入到Word文档中

现在用手机可以非常方便地将手机的任意页面&#xff08;禁止截图的App页面除外&#xff09;用截长屏的方式一次性将常常的页面内容截图下来&#xff0c;这些长页面通常是通常是聊天记录或各种文章等。 截图下来后&#xff0c;在手机或电脑中查看倒是不会有什么问题。但是&…

maven安装以及eclipse配置maven

http://jingyan.baidu.com/article/295430f136e8e00c7e0050b9.html 必须先下载并安装JDK&#xff0c;配置JDK的环境变量JAVA_HOME&#xff0c;否则maven将无法使用 eclipse安装maven插件后必须重新定位maven到本地maven目录 如下定位&#xff1a; 为了使得Eclipse中安装的Maven…

产品2

闹钟\拉链\拼图转载于:https://www.cnblogs.com/sode/archive/2012/10/22/2733640.html

Oracle分页存储过程

create or replace package JT_P_page istype type_cur is ref cursor; --定义游标变量用于返回记录集procedure Pagination (Pindex in number, --要显示的页数索引&#xff0c;从0开始 Psql in varchar2, --产生分页…

python中加入绝对路径_理解Python中的绝对路径和相对路径

本文介绍了Python中的绝对路劲和相对路径&#xff0c;分享给大家&#xff0c;也给自己留个笔记1、绝对路径 os.path.abspath("文件名")&#xff1a;显示的是一个文件的绝对路劲eg&#xff1a; >>> import os>>> os.chdir("E:\\PycharmProject…

ASP.NET 2.0与SQL Express 2005在迁移到Windows 2003时发生数据库为只读的错误

ASP.NET 2.0和SQL Server Express 2005结合进行网站开发时&#xff0c;在VS 2005中运行时没有任何问题。当网站发布在Win Server 2003时&#xff0c;就会出现数据库无法访问的错误&#xff0c;其错误提示通常为&#xff1a;Failed to update database "D:\WEBSITES\EduTec…

python串口通讯数据过长_Python 串口通讯

摘要&#xff1a;pyserial module: https://github.com/tbusf/pyserialPython使用pyserial进行串口通信&#xff1a;http://blog.csdn.net/log1100/article/details/54380325串口通讯的python模块——pySerial :http://blog.csdn.net/dainiao01/article/details/5885122Paramet…

JS 问题集锦

【1】js页面跳转 和 js打开新窗口方法 第一种&#xff1a;<script language"javascript" type"text/javascript">window.location.href"http://www.xlfun.com/login.php?backurl"window.location.href; </script>第二种&#xff1a…

flash在影片剪辑里面跳转场景

奶奶个熊。gotoandplay有那个场景参数。在影片剪辑里面死活不行。但直接在场景里可以。后来狂百度。最后找到个可以用的解决方案。把我要跳转的场景的帧取个标签名。然后用如下的代码。在with里面继续使用gotoAndPlay的场景参数模式依旧无效。 1: on(Release){2: 3: with(_roo…

重温Observer模式--热水器·改(转载)

引言 在 C#中的委托和事件 一文的后半部分&#xff0c;我向大家讲述了Observer(观察者)模式&#xff0c;并使用委托和事件实现了这个模式。实际上&#xff0c;不使用委托和事件&#xff0c;一样可以实现Observer模式。在本文中&#xff0c;我将使用GOF的经典方式&#xff0c;再…

python删除重复值所在的行数_python – 在last中删除具有重复值的行

我有一个制表符分隔文件,看起来像这样chr1 12226559 12227059 TNFRSF1Bchr1 17051560 17052060chr1 17053279 17053779chr1 17338423 17338923 ATP13A2ATP13A2ATP13A2chr1 19577574 19578074 EMC1MRTO4chr1 19578046 19578546 EMC1MRTO4chr1 19638239 19638739 AKR7A2PQLC2PQLC…