Miller-Rabin 米勒拉宾素性检测

news2025/1/11 7:17:13

1、什么是Miller-Rabin

Miller - Rabin 算法是一种用于判断一个数是否为素数的概率性算法。在密码学等领域,经常需要快速判断一个大整数是否为素数。传统的试除法对于大整数效率极低,而 Miller - Rabin 算法能够在较短时间内以较高的概率判断一个数是否为素数。

2、相关数学基础

费马小定理

如果p是素数,a是整数且a与p互质(即 gcd(a,b)=1 ),那么eq?a%5E%7Bp-1%7D%5Cequiv%201%28modp%29。不过费马小定理的逆定理不成立,即满足eq?a%5E%7Bp-1%7D%5Cequiv%201%28modp%29的p不一定是素数。这就是为什么单纯依赖费马小定理来判断素数会有问题,Miller-Rabin算法就是在此处进行改进。

反例:卡迈克尔数(伪质数)

卡迈克尔数 
 

定义:对于合数n,如果对于所有与n互质的正整数b,都有同余式eq?b%5E%7Bn-1%7D%5Cequiv%201%28mod%20n%29成立,则称合数n为卡迈克尔数。
性质:

  • 至少是三个不同素数的乘积:每个卡迈克尔数至少是三个不同素数的乘积,例如最小的卡迈克尔数eq?561%3D3%5Ctimes%2011%5Ctimes%2017
  • 满足 Korselt 准则:卡迈克尔数的等效定义,当正合数n满足以下三个性质时,它就是一个卡迈克尔数:必须包含不止一个质因数;质因数均不重复;对于每一个能被n整除的质数p,eq?p-1 也可以被 eq?n-1 整除。


因为对于卡迈克尔数n,都有eq?b%5E%7Bn-1%7D%5Cequiv%201%28mod%20n%29成立,但n不是素数(费马小定理的逆定理不成立)

二次探测定理

如果p是奇素数,x是小于p的正整数,且eq?x%5E%7B2%7D%5Cequiv%201%28modp%29,那么eq?x%3D1或者eq?x%3Dp-1

3、算法步骤

如果先不考虑卡迈克尔数,常规判断n是否是素数(概率):枚举底数eq?a_%7Bx%7Deq?a_%7Bx%7D%20%3C%20n,判断eq?a_%7Bx%7D%5E%7Bn-1%7D%20%5Cmathbf%7Bmod%7D%20n等于多少,如果eq?a_%7Bx%7D%5E%7Bn-1%7D%20%5Cmathbf%7Bmod%7D%20n%20%3D%201,那么n大概率是素数。

但卡迈克尔数不是素数,却满足eq?a_%7Bx%7D%5E%7Bn-1%7D%20%5Cmathbf%7Bmod%7D%20n%20%3D%201,所以需要筛掉卡迈克尔数,使用Miller-Rabin算法能进行有效筛掉卡迈克尔数。

如何筛掉卡迈克尔数呢?
第一次是进行费马小定理,第二次通过二次探测原理来筛掉卡迈克尔数。

二次探测定理:
假设 p 是一个素数,那么 p 显然是奇数,所以 p-1 显然是偶数。
假设有eq?a%5E%7Bp-1%7D,p-1 是偶数,令eq?%5Cfrac%7Bp-1%7D%7B2%7D%3Dm,则有eq?a%5E%7Bp-1%7D%20%3D%20a%5E%7B%5Cfrac%7Bp-1%7D%7B2%7D%5Ctimes%202%7D%20%3D%20a%5E%7Bm%5Ctimes%202%7D%20%3D%20%28a%5E%7Bm%7D%29%5E%7B2%7D
由费马小定理得,eq?%28a%5E%7Bm%7D%29%5E%7B2%7D%5Cmathbf%7Bmod%7D%20p%3D1
那么eq?%28%28a%5E%7Bm%7D%29%5E%7B2%7D-1%29%5Cmathbf%7Bmod%7D%20p%3D0,平方差变形可得eq?%28a%5E%7Bm%7D+1%29%28a%5E%7Bm%7D-1%29%5Cmathbf%7Bmod%7Dp%3D0,则说明eq?a%5E%7Bm%7D%5Cmathbf%7Bmod%7Dp%20%3D%201eq?a%5E%7Bm%7D%5Cmathbf%7Bmod%7Dp%20%3D%20p-1

也就是说,第一次是进行了费马小定理eq?%28a%5E%7Bm%7D%29%5E%7B2%7D%5Cmathbf%7Bmod%7D%20p%3D1,但此时还没筛去卡迈克尔数,就需要通过判断eq?a%5E%7Bm%7D%5Cmathbf%7Bmod%7Dp%20%3D%201eq?a%5E%7Bm%7D%5Cmathbf%7Bmod%7Dp%20%3D%20p-1是否成立,如果成立则说明不是卡迈克尔数且大概率是素数,否则不是素数。

如果将 p-1=t\times 2^{m},可得a^{p-1} = a^{t\times 2^{m}},令a^{t\times 2^{i}},0\leq i\leq m,可得序列a^{t},(a^{t})^{2},(a^{t})^{3},...,a^{p-1},通过同余定理,可得序列每一项mod p后的序列为,由同余定理得知,mod p后的序列里,如果是x ->...-> -1 -> 1...序列中间有一个-1的,那么-1之后就只能是1;如果中间没有-1,那么之后也就不会是1;所以有:

  1. p是质数:要么起始就是1,要么中间出现-1
  2. p是合数:中间没有出现-1

9c8329fc5e164e04b17543bc5d446e5a.png

4、代码实现

python

import random
def miller_rabin(n, k):
    if n == 2:
        return True
    if n % 2 == 0:
        return False
    # 分解n - 1为2^s * d的形式
    s = 0
    d = n - 1
    while d % 2 == 0:
        s += 1
        d //= 2
    for _ in range(k):
        a = random.randint(2, n - 2)
        x = pow(a, d, n)
        if x == 1 or x == n - 1:
            continue
        for _ in range(s - 1):
            x = pow(x, 2, n)
            if x == n - 1:
                break
        else:
            return False
    return True

cpp

#include <iostream>
#include <cstdlib>
#include <ctime>

// 快速幂取模运算,用于计算 (a^b) % m
int pow_mod(int a, int b, int m) {
    int result = 1;
    a %= m;
    while (b > 0) {
        if (b & 1) {
            result = (result * a) % m;
        }
        a = (a * a) % m;
        b >>= 1;
    }
    return result;
}

// Miller-Rabin素性测试算法
bool miller_rabin(int n, int k) {
    if (n == 2) return true;
    if (n % 2 == 0 || n < 2) return false;

    // 分解 n - 1 为 2^s * d 的形式
    int s = 0;
    int d = n - 1;
    while (d % 2 == 0) {
        s++;
        d /= 2;
    }

    // 进行k轮测试
    for (int i = 0; i < k; i++) {
        int a = rand() % (n - 3) + 2;  // 选取 [2, n - 2] 之间的随机数作为底数
        int x = pow_mod(a, d, n);
        if (x == 1 || x == n - 1) continue;

        bool composite = true;
        for (int r = 1; r < s; r++) {
            x = pow_mod(x, 2, n);
            if (x == n - 1) {
                composite = false;
                break;
            }
        }
        if (composite) return false;
    }
    return true;
}

//测试
int main() {
    srand(static_cast<unsigned int>(time(nullptr)));
    int num = 121;  // 这里可以替换成你想要测试的数
    int round = 5;  // 测试轮数,可以根据需求调整
    if (miller_rabin(num, round)) {
        std::cout << num << " 可能是素数" << std::endl;
    } else {
        std::cout << num << " 是合数" << std::endl;
    }
    return 0;
}

5、时间复杂度

dff009a188844fce8197261fc5d13904.png

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

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

相关文章

【MySQL系列】MySQL 中的 SQL_MODE 设置:ANSI_QUOTES 选项解析与应用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

HarmonyOS 5.0应用开发——Ability与Page数据传递

【高心星出品】 文章目录 Ability与Page数据传递Page向Ability传递数据Ability向Page传递数据 Ability与Page数据传递 基于当前的应用模型&#xff0c;可以通过以下几种方式来实现UIAbility组件与UI之间的数据同步。 使用EventHub进行数据通信&#xff1a;在基类Context中提供…

MFC扩展库BCGControlBar Pro v36.0新版亮点:黑色主题中的自动反转图标

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v36.0已全新发布了&#xff0c;这个版本在黑暗主题中添加自动图标反转、新增一个全新的S…

查找 排序算法(系列)

复习一下排序算法吧&#xff0c;数据结构有点难&#xff0c;虽然我已经看过一遍了&#xff0c;重温一遍还是很有收获&#xff01; 本文会出一系列&#xff08;主讲算法排序&#xff09;&#xff0c;欢迎订阅&#xff01;&#xff01;&#xff01; Python中常用的排序算法有以…

Y20030053 JSP+SSM+MYSQL+LW+旅游系统的设计与实现 源码 配置 文档 全套资料

旅游系统的设计与实现 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 摘 要 随着旅游业的蓬勃发展和人们对休闲度假需求的不断增加&#xff0c;旅游业管理面临着越来越多的挑战。为了提高管理效率、优化客户体验并增强市场竞争力&#xff0c;本文介绍…

3D 生成重建016-SA3D从nerf中分割一切

3D 生成重建016-SA3D从nerf中分割一切 文章目录 0 论文工作1 方法介绍2 实验结果 0 论文工作 1 SAM的背景和目标&#xff1a; SAM 是一种强大的二维视觉基础模型&#xff0c;能够在 2D 图像中进行任意物体的分割。传统上&#xff0c;SAM 在二维空间表现出色&#xff0c;但其无…

Leetcode—374. 猜数字大小【简单】

2024每日刷题&#xff08;202&#xff09; Leetcode—374. 猜数字大小 C实现代码 /** * Forward declaration of guess API.* param num your guess* return -1 if num is higher than the picked number* 1 if num is lower than the picked number* …

数字孪生与大型模型强强联合,共塑工业制造崭新前景

随着新一代信息技术与实体经济的加速融合&#xff0c;工业领域的数字化、智能化转型趋势愈发显著&#xff0c;孕育出一系列制造业数字化转型的新模式与新业态。在此背景下&#xff0c;数字孪生技术作为关键支撑力量&#xff0c;正在全球范围内迅速崛起并得到广泛应用&#xff0…

vue+mars3d点击图层展示炫酷的popup弹窗

展示效果 目录 一&#xff1a;叠加数据图层到地图上&#xff0c;此时需要使用bindPopup绑定popup 二、封装自定义的popup&#xff0c;样式可以自行调整 一&#xff1a;叠加数据图层到地图上&#xff0c;此时需要使用bindPopup绑定popup 这里我根据数据不同&#xff0c;展示的…

springboot利用easypoi实现简单导出Excel

vue springboot利用easypoi实现简单导出 前言一、easypoi是什么&#xff1f;二、使用步骤 1.传送门2.前端vue3.后端springboot 3.1编写实体类&#xff08;我这里是dto,也一样&#xff09;3.2控制层结尾 前言 今天玩了一下springboot利用easypoi实现excel的导出&#xff0c;以前…

Milvus attu - docker 使用 及 版本兼容

文章目录 版本查看attu 和 milvus 的兼容性Docker 加载attu docker 合并到 Milvus文件管理使用 docker compose 挂在 Milvus,登录 attu 出现报错: Error: Failed to connect to Milvus: Error: 1 CANCELLED: Call cancelled 于是检查兼容问题 版本查看 Milvus 版本发布: htt…

洛谷 P1957 口算练习题 C语言

题目&#xff1a; https://www.luogu.com.cn/problem/P1957 题目描述 王老师正在教简单算术运算。细心的王老师收集了 ii 道学生经常做错的口算题&#xff0c;并且想整理编写成一份练习。 编排这些题目是一件繁琐的事情&#xff0c;为此他想用计算机程序来提高工作效率。王老…

el-select 修改样式

这样漂亮的页面&#xff0c;搭配的却是一个白色风格的下拉框 &#xff0c;这也过于刺眼。。。 调整后样式为&#xff1a; 灯红酒绿总有人看着眼杂&#xff0c;但将风格统一终究是上上选择。下面来处理这个问题。 分为两部分。 第一部分&#xff1a;是修改触发框的样式 第二部…

Proteus中添加新元件库

手上村&#xff1a;本来打算在Proteus中设计充电电路&#xff0c;发现软件自带的元器件库中没有我想要充电芯片。因此&#xff0c;看了其他大神的导入新的元器件步骤&#xff0c;建立自己的元器件库&#xff01;自己也来记录一波&#xff01;话不多说&#xff0c;赶紧上菜&…

数字IC前端学习笔记:脉动阵列的设计方法学(以串行FIR滤波器为例)

相关阅读数字IC前端_日晨难再的博客-CSDN博客https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 引言 脉动结构&#xff08;也称为脉动阵列&#xff09;表示一种有节奏地计算并通过系统传输数据的处理单元(PEs)网络。这些处理单元有规律地…

springboot mvn 打包,jar和资源文件分离打包

默认打包方式如下&#xff1a; <build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><execution…

5G CPE核心器件-基带处理器(三)

5G CPE 核心器件 -5G基带芯片 基带芯片简介基带芯片组成与结构技术特点与发展趋势5G基带芯片是5G CPE中最核心的组件,负责接入5G网络,并进行上下行数据业务传输。移动通信从1G发展到5G,终端形态产生了极大的变化,在集成度、功耗、性能等方面都取得巨大的提升。 基带芯片简…

【JavaWeb后端学习笔记】SpringBoot框架下Http请求参数接收

Http请求参数接收 1、简单参数2、实体参数3、数组参数4、集合参数5、日期参数6、Json格式参数&#xff08;常用&#xff09;7、路径参数&#xff08;常用&#xff09;8、接收请求参数常用的几个注解 Http请求能携带各种格式的请求参数。因此也就需要不同的接收方式。 1、简单参…

在 MacOS 上为 LM Studio 更换镜像源

在 MacOS 之中使用 LM Studio 部署本地 LLM时&#xff0c;用户可能会遇到无法下载模型的问题。 一般的解决方法是在 huggingface.co 或者国内的镜像站 hf-mirror.com 的项目介绍卡页面下载模型后拖入 LM Studio 的模型文件夹。这样无法利用 LM Studio 本身的搜索功能。 本文将…

Vue工程化开发中各文件的作用

1.main.js文件 main.js文件的主要作用&#xff1a;导入App.vue&#xff0c;基于App.vue创建结构渲染index.html。