初等数论--同余--MILLER-RABIN素性检测算法优化

  • Euler theorem、Fermat's little theorem
  • Primality Test: Fermat、MILLER-RABIN、IMPROVED
  • 代码验证

博主是初学初等数论(整除+同余+原根),本意是想整理一些较难理解的定理、算法,加深记忆也方便日后查找;如果有错,欢迎指正。
我整理成一个系列:初等数论,方便检索。

这一章不同于前几章,是我自己总结的素性检测算法规律以及探索一些可优化的地方。

Euler theorem、Fermat’s little theorem

具体的定理内容以及证明,我在前几章已经记录过。

  • 欧拉定理:设n∈N+,a∈Z,(a,n)=1,则aφ(n)≡1(modn)欧拉定理:设n\in N^+,a\in Z,(a,n)=1,则a^{\varphi(n)}\equiv 1(mod n)欧拉定理:设n∈N+,a∈Z,(a,n)=1,则aφ(n)≡1(modn)
  • 费马小定理:设n为素数,a∈Z,则an≡a(modn)费马小定理:设n为素数,a\in Z,则a^n\equiv a(mod n)费马小定理:设n为素数,a∈Z,则an≡a(modn)

可以看出,Fermat’s little theorem的条件更严格,要求是n为素数,而欧拉定理只要求a与n互素即可,并没有要求n本身为素数。

目前我学习到的素性检测算法都是以Fermat’s little theorem作为依据,应该是因为Fermat’s little theorem的条件,必须是素数。下面我具体来谈谈我学习到的几个素性检测算法。

Primality Test: Fermat、MILLER-RABIN、IMPROVED

素性检测算法的目的都是一样的:通过满足某些条件,来判断是素数的概率,检测越多次概率越大,但是没法把所有数都遍历,所以概率不会到100%。

Fermat’s little theorem是通过n是素数的条件,推出a,n满足哪些结论。素性检测算法的手段也都是一样的:通过a,n或者其他参数满足哪些条件,判断n是素数的概率。

  • Fermat素性检测算法:n为奇数,通过多次随机取b∈Z,有(b,n)=1,判断bn−1≡0(modn)b\in Z,有(b,n)=1,判断b^{n-1}\equiv 0(mod n)b∈Z,有(b,n)=1,判断bn−1≡0(modn)来逐步提高n是素数的概率。(n如果是奇合数,则被称为对于基b的伪素数)
  • MILLER-RABIN算法:更具化了n,使得n的条件更多,“n−1=2st,其中t为奇数,2∤t,通过多次随机取b∈Z,(b,n)=1,如果b和n满足条件bt≡1(modn),或存在整数r,0≤r<s,使得b2rt≡−1(modn)"“n-1=2^st,其中t为奇数,2\nmid t,通过多次随机取b\in Z,(b,n)=1,如果b和n满足条件b^t\equiv 1(mod n),或存在整数r,0\le r< s,使得b^{2^rt}\equiv -1(mod n)"“n−1=2st,其中t为奇数,2∤t,通过多次随机取b∈Z,(b,n)=1,如果b和n满足条件bt≡1(modn),或存在整数r,0≤r<s,使得b2rt≡−1(modn)"来逐步提高n是素数的概率。(n如果是奇合数,则被称为对于基b的强伪素数)
  • IMPROVED算法:更更具化了n,使得n的条件更多,“n−1=2k3lm,其中2∤m且3∤m,通过多次随机取b∈Z,(b,n)=1,如果b和n满足条件bm≡1(modn),或存在整数q,0≤q<l,使得b2⋅3qm+b3qm≡−1(modn)",或存在整数r,0≤r<k,使得b2r3lm≡−1(modn)"“n-1=2^k3^lm,其中2\nmid m且3\nmid m,通过多次随机取b\in Z,(b,n)=1,如果b和n满足条件b^m\equiv 1(mod n),或存在整数q,0\le q< l,使得b^{2·3^qm}+b^{3^qm}\equiv -1(mod n)",或存在整数r,0\le r< k,使得b^{2^r3^lm}\equiv -1(mod n)"“n−1=2k3lm,其中2∤m且3∤m,通过多次随机取b∈Z,(b,n)=1,如果b和n满足条件bm≡1(modn),或存在整数q,0≤q<l,使得b2⋅3qm+b3qm≡−1(modn)",或存在整数r,0≤r<k,使得b2r3lm≡−1(modn)"来逐步提高n是素数的概率。

可以看出,条件逐渐变得严格。有时候某些数可以通过Fermat素性检测算法,却不能通过MILLER-RABIN算法;可以通过MILLER-RABIN算法却不能通过IMPROVED算法。

这是因为比对这两种算法,其实是把Fermat素性检测算法的一个条件进一步拆分成(s+1)个条件,MILLER-RABIN算法继续到IMPROVED算法,也是把1个条件继续拆分成(l+1)个条件。

我们是通过条件中有“0”项来判断整体为“0”,从而素数可能性提高。也就是说,条件项皆不为0,则不能通过素性检测。有没有可能某一个数对于IMPROVED算法,皆不为0,可是对于MILLER-RABIN算法为0呢?应该是有的,即(l+1)个分项不为0,但是(l+1)个分项的乘积为0。即可能存在"b2⋅3qm+b3qm≡−1(modn)不满足,bm≡1(modn)不满足,却满足bt≡1(modn).b^{2·3^qm}+b^{3^qm}\equiv -1(mod n)不满足,b^m\equiv 1(mod n)不满足,却满足b^t\equiv 1(mod n).b2⋅3qm+b3qm≡−1(modn)不满足,bm≡1(modn)不满足,却满足bt≡1(modn)."

代码验证

具体数字需要代码实现验证,此工作正在进行中……

实现了Fermat素性检测算法,和MILLER-RABIN素性检测算法,以2为底,primeTable是0-10w内所有素数,生成算法没有贴上来。

以下是Fermat素性检测算法代码:

from random import random# 利用辗转相除法求最大公因数
def BFactor(a, b):# 若b>a,则交换两个数的值if (b > a):t = aa = bb = tr = b  # 初始化rwhile (r != 0):r = a % b  # r为a/b的余数a = bb = rreturn a  # 得到最后的a为(a,b)# n = int(input("请输入需要检测的整数n:"))
# K = int(input("请输入循环次数k:"))False_Prime_founded = []def fermat_test(n, K):k = 0while (k < K):flag = False# while (not flag):#     b = int(random() * (n - 4) + 2)  # 生成一个[2,n-2]之间的随机整数#     if (b >= 2 and b <= n - 2):#         flag = Trueb = 2factor = BFactor(b, n)  # 计算(b,n)r = (b ** (n - 1)) % n  # 计算b^(n-1)modnprint("k=" + str(k + 1) + "时,取b=" + str(b), end=",")print("g=(" + str(b) + "," + str(n) + ")=" + str(factor), end=',')print("r=" + str(b) + "^" + str(n - 1) + "(mod " + str(n) + ")=" + str(r), end=',')if (factor > 1):print("故n=" + str(n) + "为合数")breakelif (r != 1):print("故n=" + str(n) + "为合数")breakelse:print("故n=" + str(n) + "可能为素数")k += 1if (k == K and n not in primeTable):False_Prime_founded.append(n)print("所以, n=" + str(n) + "可能为素数,n为素数的概率为" + str((1 - 1 / (2 ** k)) * 100) + "%")def run():for i in range(5, 100000):print(i)fermat_test(i, 1)print("找到的素数:" + str(False_Prime_founded))# 遍历整数,直至找到伪素数run()

以下是MILLER-RABIN素性检测算法代码:

import decimal
from random import random
from decimal import Decimal, localcontext
import mathdecimal.getcontext().prec = 100000000# 辗转相除法找最大公因数(a,b)
def BFactor(a, b):if b > a:t = ab = ta = bq = bwhile (q != 0):q = a % ba = bb = qreturn b# n = int(input("请输入需要检测的整数n:"))
# K = int(input("请输入循环次数k:"))MI_False_Prime_founded = []def MILLER_RABIN(n, K):k = 0while (k < K):t = n - 1while (t % 2 == 0):print(t)t /= 2print("n: " + str(n) + "t: " + str(t))print("n-1/t:" + str((n - 1) / t))s = int(math.log((n - 1) / t, 2))print("s" + str(s))flag = False# while (not flag):#     b = int(random() * (n - 4) + 2)  # 生成一个[2,n-2]之间的随机整数#     if (b >= 2 and b <= n - 2):#         flag = Trueb = 2factor = BFactor(b, n)  # 计算(b,n)print("t: " + str(t))x = Decimal(Decimal(pow(Decimal(b), Decimal(t))) % Decimal(n))  # 计算b^tmodny = []print("vafac")for r in range(1, s):print("avsdfavafaa")print("s" + str(s))y.append(Decimal(pow(b, (Decimal(pow(2, r) * t)))))print(y)# print("包含2的次幂:"+str(y))# print("k=" + str(k + 1) + "时,取b=" + str(b), end=",")# print("g=(" + str(b) + "," + str(n) + ")=" + str(factor), end=',')# # print("r=" + str(b) + "^" + str(n - 1) + "(mod " + str(n) + ")=" + str(r), end=',')for i in y:print("i: " + str(i))print("n: " + str(n))print("i%n: " + str(int(i) % n))if int(i) % n == n - 1:print("故n=" + str(n) + "可能为素数")MI_False_Prime_founded.append(n)breakif factor > 1:print("factor: " + str(factor))print("数字1")print("故n=" + str(n) + "为合数")breakif x == 1 or x == -1:print("数字2")print("故n=" + str(n) + "可能为素数")MI_False_Prime_founded.append(n)# if p== -1 for p in y:#     if p#     print("故n=" + str(n) + "可能为素数")#     k = k + 1else:print("故n=" + str(n) + "为合数")k += 1# if (k == K):#     print("数字3")#     MI_False_Prime_founded.append(n)#     print("所以, n=" + str(n) + "可能为素数,n为素数的概率为" + str((1 - 1 / (2 ** k)) * 100) + "%")def run():for i in primeTable:print(i)MILLER_RABIN(i, 1)print("找到的素数:" + str(MI_False_Prime_founded))primeTable = [341, 561, 645, 1105, 1387, 1729, 1905, 2047, 2465, 2701, 2821, 3277, 4033, 4369, 4371, 4681, 5461, 6601,7957, 8321, 8481, 8911, 10261, 10585, 11305, 12801, 13741, 13747, 13981, 14491, 15709, 15841, 16705,18705, 18721, 19951, 23001, 23377, 25761, 29341, 30121, 30889, 31417, 31609, 31621, 33153, 34945, 35333,39865, 41041, 41665, 42799, 46657, 49141, 49981, 52633, 55245, 57421, 60701, 60787, 62745, 63973, 65077,65281, 68101, 72885, 74665, 75361, 80581, 83333, 83665, 85489, 87249, 88357, 88561, 90751, 91001, 93961]run()

找到的伪素数分别是:

  • Fermat算法找到的“素数”:[341, 561, 645, 1105, 1387, 1729, 1905, 2047, 2465, 2701, 2821, 3277, 4033, 4369, 4371, 4681, 5461, 6601, 7957, 8321, 8481, 8911, 10261, 10585, 11305, 12801, 13741, 13747, 13981, 14491, 15709, 15841, 16705, 18705, 18721, 19951, 23001, 23377, 25761, 29341, 30121, 30889, 31417, 31609, 31621, 33153, 34945, 35333, 39865, 41041, 41665, 42799, 46657, 49141, 49981, 52633, 55245, 57421, 60701, 60787, 62745, 63973, 65077, 65281, 68101, 72885, 74665, 75361, 80581, 83333, 83665, 85489, 87249, 88357, 88561, 90751, 91001, 93961]

  • MILLER-RABIN算法找到的“素数”:[2047, 3277, 4033, 4681, 8321, 15841, 29341, 42799, 49141, 52633, 65281, 74665, 80581, 85489, 88357, 90751]

初等数论--同余--MILLER-RABIN素性检测算法优化相关推荐

  1. 初等数论--同余--MILLER-RABIN素性检测算法

    初等数论--同余--MILLER-RABIN素性检测算法 博主是初学初等数论(整除+同余+原根),本意是想整理一些较难理解的定理.算法,加深记忆也方便日后查找:如果有错,欢迎指正. 我整理成一个系列: ...

  2. 初等数论--同余--Fermat素性检测算法(为什么每次概率改变1/2)

    初等数论--同余--Fermat素性检测算法(为什么每次概率改变1/2) 为什么每次概率改变1/2 博主是初学初等数论(整除+同余+原根),本意是想整理一些较难理解的定理.算法,加深记忆也方便日后查找 ...

  3. 米勒-拉宾素性检测算法

    米勒-拉宾素性检测就是目前应用比较广的一种随机化素性检测算法. 它是基于下面两个定理: (费马小定理)如果 p 为素数,且 a 无法被 p 整除,则对于所有大于0小于 p 的整数 a,有 ap−1≡1 ...

  4. Harris角点检测算法优化

    Harris角点检测算法优化 一.综述 用 Harris 算法进行检测,有三点不足:(1 )该算法不具有尺度不变性:(2 )该算法提取的角点是像素级的:(3 )该算法检测时间不是很令人满意. 基于以上 ...

  5. 目标检测算法优化技巧

    论文:Bag of Freebies for Training Object Detection Neural Networks 论文链接:https://arxiv.org/abs/1902.041 ...

  6. C++Miller Rabin算法的实现(附完整源码)

    C++Miller Rabin算法的实现算法 C++Miller Rabin算法的实现算法完整源码(定义,实现,main函数测试) C++Miller Rabin算法的实现算法完整源码(定义,实现,m ...

  7. 基因组大数据变异检测算法的并行优化

    基因组大数据变异检测算法的并行优化 基因组大数据变异检测算法的并行优化 崔英博1, 黄春1, 唐滔1, 杨灿群1, 廖湘科1, 彭绍亮2,3 1 国防科技大学计算机学院,湖南 长沙 410073 2 ...

  8. 素数判定算法 MILLER RABIN

    入门级筛素数--试除法,复杂度O(n^2) bool rmprime( long long n ) {for(long long i = 2; i <= sqrt(n) ; i++) if(n% ...

  9. (Miller Rabin算法)判断一个数是否为素数

    (Miller Rabin算法)判断一个数是否为素数 1.约定 x%y为x取模y,即x除以y所得的余数,当x<y时,x%y=x,所有取模的运算对象都为整数. x^y表示x的y次方.乘方运算的优先 ...

最新文章

  1. 这就是我为什么推荐使用var aa = for (var i = 0, l = aa.length; i < l; i++) {var a = aa[i];}循环的原因,每秒最快可以执行4000+次!
  2. 织梦添加搜索框里的提示消息
  3. php curl 不验证ssl,PHP Curl https跳过ssl证书认证报错记录及解决
  4. JAVA基础_修饰符
  5. select事件有哪些_Android 深入底层:Linux事件管理机制 epoll
  6. C++中枚举的用法(比较全面)(转)
  7. 微信红包功能(含示例demo)
  8. php curl详解用法[真的详解]
  9. POJ-1260 Pearls---DP
  10. 构建高性能.NET应用之配置高可用IIS服务器-第五篇 IIS常见问题之:工作进程回收机制(中)...
  11. SQL Server 高可用性(一)AlwaysOn 技术
  12. DataRowView 笔记
  13. 关于数据分析部门组织架构的探讨
  14. 三维建模软件:Rhino 7 for Mac
  15. java数组基本用法(数组的声明/初始化及一些常用的数组操作)
  16. matlab2012b破解版安装
  17. [病毒木马] 什么是LSP劫持
  18. 【算法•日更•第五十五期】知识扫盲:什么是卡常数?
  19. 290万人考研:所有的不平凡,从不认命开始
  20. TDK是什么意思,TDK怎么写?怎么利于SEO优化?

热门文章

  1. centos yum mysql_CentOS 7 yum安装配置MySQL5.7教程
  2. 将query存进数组 php,thinkphp下通过QueryList获取网站指定数据并封装成数组,存入数据库...
  3. 2020年度国家绿色数据中心名单正式发布
  4. 数据机房局部过热与节能降耗解决方案
  5. 疫情启示录:控疫复工背后的数据中心价值,市场这样说
  6. 数据中心巡检实操之UPS及电池
  7. 数据中心机房供电需求有哪些?存在哪些电能质量问题?
  8. 计算机设置从光盘启动怎么办,设置BIOS从光盘启动教程
  9. mysql 语句怎样修饰约束_MySQL中的约束,添加约束,删除约束,以及一些其他修饰讲解...
  10. ML之xgboost:利用xgboost算法(自带方式)训练mushroom蘑菇数据集(22+1,6513+1611)来预测蘑菇是否毒性(二分类预测)