引语:在数论中,对于素数的研究一直就很多,素数测试的方法也是非常多,如埃式筛法,6N±1法,或者直接暴力判(试除法)。但是如果要判断比较大的数是否为素数,那么传统的试除法和筛法都不再适用。所以我们需要学习Miller_Rabin算法。

知识准备 + 算法推导:

1.威尔逊定理:若p是素数,则 (p-1) !≡ -1(mod p).

2.有趣的是,威尔逊定理的逆命题也是正确的:设n是正整数且 n ≥ 2 ,若 (n-1) !≡ -1(mod n),则是素数.

很多朋友可能在学习的时候会碰到威尔逊定理,它主要是告诉我们,它的逆定理给出了一种素性检验的方法(其实用的少,原因在后),遗憾的是,这不是一个实用的检验法,因为这需要进行(n-2)次模n的乘法运算才能得到 (n-1)! 模n的值,运算量达到了O( n(log2n)2 ) 次位运算。

行吧,那我们只能另谋出路了。

3.费马小定理:设是一个素数,a是一个正整数且p不整除a ,则 ap-≡ 1(mod p).

4.伪素数:令b是一个正整数. 若n是一个正合数且 bn ≡ b(mod n),则称n为以b为基的伪素数(有时也称费马伪素数)。(唉~,这是虚伪的素数,它爱着费马测试,却是合数)。

辣个男人,它来了!

那么基于费马小定理,Miller检验:假如n是素数,且gcd(a,n) = 1,那么 an-1 ≡ 1(mod n).如果 an-1 ≡ 1(mod n)(a为任意小于n的正整数),则可近似认为n是素数。取多个底进行试验,次数越多,n为素数的概率越大。

5.【重头戏】卡迈尔数:一个合数 n 若对所有满足 gcd(b, n) = 1 的正整数b都有 bn-1 ≡ 1(mod n)成立,则称为卡迈尔(Carmichael)数或者称为绝对伪素数(不得不服,6601)。

6.二次探测定理:如果p是一个素数,且 0 < x < p,则方程 x2%p = 1的解为 x = 1 或 x = p - 1.

辣个男人,它又来了!

既然有卡迈尔数的存在,那么需要排除卡迈尔数,可以根据二次定理,在利用费马小定理计算 bn-1%的过程中增加对整数n的二次探测,一旦发现违背二次探测条件,即得出n不是素数的结论。

这里,令 n - 1 = 2rs,其中s是一个奇数,随机选择一个a, 1 ≤ a ≤ n-1 ,如果  a2s ≡ 1(mod n) 并且 a≡ 1 (mod n) 或 a≡ (n-1) (mod n),则通过了测试,但如果后面的测试,在a的指数不断乘2的过程中,如果出现没有通过测试,则不是素数。如果取了几次底a,都通过了测试,那么我们就可以接近100%的认为n是素数。

代码:

#define LL long long
//这里可以采用随机数,我用的是准备好的基数
const int Test[] = {2, 3, 5, 7, 11, 13, 17, 19};
const int Times = 8;  //可以调整 LL Multi(LL a, LL b, LL mod)
{
LL ans = 0;
while(b)
{
if(b&1)
{
ans = (ans + a)%mod;
}
a = (a+a)%mod; //要这么写
b>>=1;
}
return ans;
} LL Pow(LL a, LL b, LL mod)
{
LL ans = 1;
while(b)
{
if(b&1)
{
ans = Multi(ans, a, mod);
}
b>>=1;
a = Multi(a, a, mod);
}
return ans;
} bool Miller_Rabin(LL n)
{
if(n < 2) return false;
LL s = n-1, t = 0;
while( !(s&1) )
{
t++;
s>>=1;
}
for(int i = 0; i < Times; i++)
{
if(n == Test[i])
return true;
LL x = Pow(Test[i], s, n);
LL next = x;
for(int j = 0; j < t; j++)
{
next = Multi(x, x, n);
if(next == 1 && x != 1 && x != n-1)
return false;
x = next;
}
if(x != 1)
return false;
}
return true;
}

  

Miller_Rabin素数测试【学习笔记】的更多相关文章

  1. 数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test

    Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 29046   Accepted: 7342 Case ...

  2. hdu 6169 Senior PanⅡ Miller_Rabin素数测试+容斥

    Senior PanⅡ Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Pr ...

  3. Miller_Rabin 素数测试

    费马定理的逆定理几乎可以用来判断一个数是否为素数,但是有一些数是判断不出来的,因此,Miller_Rabin测试方法对费马的测试过程做了改进,克服其存在的问题. 推理过程如下(摘自维基百科): 摘自另 ...

  4. Web安全测试学习笔记-DVWA-SQL注入-2

    接上一篇SQL注入的学习笔记,上一篇我通过报错信息得知后台数据库是MySQL(这个信息非常重要~),然后通过SQL注入拿到了用户表的所有行,其实我们还可以通过MySQL的特性来拿更多的信息. 1. 获 ...

  5. 【数学】【筛素数】Miller-Rabin素性测试 学习笔记

        Miller-Rabin是一种高效的随机算法,用来检测一个数$p$是否是素数,最坏时间复杂度为$\log^3 p$,正确率约为$1-4^{-k}$,$k$是检验次数. 一.来源     Mil ...

  6. Miller_Rabin素数测试

    #include<iostream> #include<cmath> #include<cstdio> #include<cstring> #inclu ...

  7. Miller-Rabin素数测试学习小计

    1.Miller-Rabin是干啥的?它是用来检测一个数字(一般是很大的数字)是不是素数: 2.Miller-Rabin算法基于的两个定理: (1)费尔马小定理:如果p是一个素数,且0<a< ...

  8. Web安全测试学习笔记 - DVWA+PHP环境搭建

    DVWA(Damn Vulnerable Web Application),是一个用PHP编写的,作为Web安全测试练习平台的合法环境(毕竟咱不能为了练习就随便找个网站去攻击...),也就是俗称的靶场 ...

  9. QTP测试学习笔记

    QuickTest Professional(简称QTP)功能自动化测试,原属于Mercury Interactive公司产品,2006年7月被惠普公司收购了,通过安装文件目录可以看到,都是默认放在C ...

随机推荐

  1. C++——多线程

    1.多进程和多线程:进程是一个总任务,一个进程可能包含多个线程. 2.并行和并发: 并发的关键是你有处理多个任务的能力,不一定要同时. 并行的关键是你有同时处理多个任务的能力. 3.共享数据的管理和线 ...

  2. c++ 装饰模式(decorate)

    装饰模式:动态地给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类 更为灵活.有时我们希望给某个对象而不是整个类添加一些功能.比如有一个手机,允许你为手机添加特性,比如增加挂件.屏幕贴 ...

  3. 724. Find Pivot Index 找到中轴下标

    [抄题]: Given an array of integers nums, write a method that returns the "pivot" index of th ...

  4. jq获取table总行数

    var rows = $('table').find("tr").length;

  5. SQLAlchemy 进阶

    SQLAlchemy使用 1.执行原生SQL语句 from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engin ...

  6. 第19章-使用Spring发送Email

    1 配置Spring发送邮件 Spring Email抽象的核心是MailSender接口.顾名思义,MailSender的实现能够通过连接Email服务器实现邮件发送的功能,如图19.1所示. 图1 ...

  7. 如何杀死一个已经detached的screen会话?

    如果向杀死一个已经detached的screen会话,可以使用以下命令: screen -X -S seesion-id quit 举例如下: [root@localhost ~]# screen - ...

  8. Javascript脚本 :Function 对象的定义和使用

    javascript  Function 对象的定义 创建函数的语法:var myFunction=new Function(arg1,arg2,...agrN,body);agrN 为函数的参数,b ...

  9. MVC5中 在更新 Microsoft.Aspnet.Identity 后编译器错误

    环境:vs2013预览版chs,我试着创建vb.net web应用,从对话框中选择MVC和WebAPI.编译ok了.通过NuGet管理器更新了Microsoft.Aspnet.Identity.Cor ...

  10. ECS服务里或者阿里云服务器的二级域名设置方法

    我们要实现的效果是,xuxinshuai.abc.com ,具体怎么实现,看下面的流程 第一步:备案域名要有,假如就是www.abc.com 第二步:网站的服务器是IIS的情况下,在部署网站时,需要设 ...