Python实现Tonelli-Shanks算法

目录

  • Python实现Tonelli-Shanks算法
    • 引言
    • 一、Tonelli-Shanks算法的理论基础
      • 1.1 模平方根的定义
      • 1.2 Tonelli-Shanks算法的原理
      • 1.3 Tonelli-Shanks算法的复杂度
    • 二、Tonelli-Shanks算法的Python实现
      • 2.1 基本实现
      • 2.2 案例一:求多个模平方根
        • 2.2.1 实现代码
      • 2.3 案例二:应用于密码学中的Diffie-Hellman密钥交换
        • 2.3.1 实现代码
      • 2.4 案例三:性能分析
        • 2.4.1 实现代码
    • 三、Tonelli-Shanks算法的应用领域
    • 四、结论

Python实现Tonelli-Shanks算法

引言

Tonelli-Shanks算法是一个用于求解模平方根的问题,特别是在模素数的情况下。给定一个素数 p p p 和一个整数 a a a,如果存在一个整数 x x x,使得 x 2 ≡ a m o d p x^2 \equiv a \mod p x2amodp,则称 a a a 是模 p p p 的一个平方剩余。Tonelli-Shanks算法能够高效地找到这样的 x x x(如果存在)。

本文将详细介绍Tonelli-Shanks算法的理论基础,逐步实现该算法,并通过多个实例展示其在Python中的应用。我们将采用面向对象的设计方法,以便使代码结构清晰,易于理解和扩展。

一、Tonelli-Shanks算法的理论基础

1.1 模平方根的定义

模平方根问题可以表述为:给定一个素数 p p p 和一个整数 a a a,求解方程:
x 2 ≡ a m o d p x^2 \equiv a \mod p x2amodp
如果 a a a p p p 的平方剩余,则存在至少一个解 x x x。否则,方程无解。

1.2 Tonelli-Shanks算法的原理

Tonelli-Shanks算法的基本步骤如下:

  1. 检查平方剩余性:首先检查 a a a 是否是 p p p 的平方剩余。如果不是,则算法结束。
  2. 找到二次非剩余:寻找一个二次非剩余 z z z
  3. 设定参数:设置 q q q s s s,其中 q q q p − 1 p - 1 p1 的最大偶数因子, s s s p − 1 p - 1 p1 的二进制表示中的零的个数。
  4. 计算初始值:计算初始值 M M M c c c R R R T T T
  5. 迭代:迭代计算,直到 T ≡ 0 m o d p T \equiv 0 \mod p T0modp,每次迭代会更新 R R R T T T

1.3 Tonelli-Shanks算法的复杂度

Tonelli-Shanks算法的时间复杂度为 O ( log ⁡ 2 p ) O(\log^2 p) O(log2p),这使得它在模素数的情况下非常高效,尤其是在 p p p较大的情况下。

二、Tonelli-Shanks算法的Python实现

接下来,我们将使用Python实现Tonelli-Shanks算法,并通过面向对象的方法进行代码组织。

2.1 基本实现

class TonelliShanks:def __init__(self, p):if p % 4 != 3:raise ValueError("此算法仅适用于模素数 p,且 p ≡ 3 (mod 4).")self.p = pdef is_quadratic_residue(self, a):"""检查 a 是否是模 p 的平方剩余"""return pow(a, (self.p - 1) // 2, self.p) == 1def find_quadratic_non_residue(self):"""找到模 p 的一个二次非剩余"""for z in range(2, self.p):if not self.is_quadratic_residue(z):return zraise ValueError("未能找到二次非剩余")def tonelli_shanks(self, a):"""Tonelli-Shanks算法"""if not self.is_quadratic_residue(a):raise ValueError(f"{a} 不是模 {self.p} 的平方剩余.")# 1. 计算 q 和 sq = self.p - 1s = 0while q % 2 == 0:q //= 2s += 1# 2. 找到二次非剩余 zz = self.find_quadratic_non_residue()# 3. 初始化参数M = sc = pow(z, q, self.p)R = pow(a, (q + 1) // 2, self.p)t = pow(a, q, self.p)# 4. 迭代while t != 0 and t != 1:# 找到 t 的最小幂 k 使得 t^(2^k) ≡ 1t2i = ti = 0for i in range(1, M):t2i = (t2i * t2i) % self.pif t2i == 1:break# 计算 b 和 db = pow(c, 1 << (M - i - 1), self.p)R = (R * b) % self.pc = (b * b) % self.pt = (t * c) % self.pM = ireturn R# 示例
try:p = 11a = 3ts = TonelliShanks(p)root = ts.tonelli_shanks(a)print(f"x^2 ≡ {a} (mod {p}) 的平方根是: {root}")
except ValueError as e:print(e)

2.2 案例一:求多个模平方根

我们可以扩展上面的实现,批量求解多个 a a a 对于同一个 p p p 的平方根。

2.2.1 实现代码
class MultipleTonelliShanks:def __init__(self, p):self.ts = TonelliShanks(p)def find_roots(self, a_values):results = {}for a in a_values:try:root = self.ts.tonelli_shanks(a)results[a] = rootexcept ValueError as e:results[a] = str(e)return results# 示例
p = 11
a_values = [3, 4, 5, 6, 7, 8]
multiple_ts = MultipleTonelliShanks(p)
results = multiple_ts.find_roots(a_values)for a, root in results.items():print(f"x^2 ≡ {a} (mod {p}) 的平方根是: {root}")

2.3 案例二:应用于密码学中的Diffie-Hellman密钥交换

Tonelli-Shanks算法可以用于实现Diffie-Hellman密钥交换中的某些步骤,尤其是在需要计算平方根的情况下。

2.3.1 实现代码
class DiffieHellman:def __init__(self, p, g, a, b):self.p = pself.g = gself.a = a  # Alice 的私钥self.b = b  # Bob 的私钥def compute_shared_key(self):A = pow(self.g, self.a, self.p)  # Alice 发送的公钥B = pow(self.g, self.b, self.p)  # Bob 发送的公钥# Alice 计算共享密钥shared_key_A = pow(B, self.a, self.p)# Bob 计算共享密钥shared_key_B = pow(A, self.b, self.p)return shared_key_A, shared_key_B# 示例
p = 23  # 素数
g = 5   # 原根
a = 6   # Alice 的私钥
b = 15  # Bob 的私钥
dh = DiffieHellman(p, g, a, b)
shared_keys = dh.compute_shared_key()
print(f"Alice 和 Bob 的共享密钥: {shared_keys}")

2.4 案例三:性能分析

我们可以实现一个性能分析工具,比较不同大小的 ( p ) 对Tonelli-Shanks算法的影响。

2.4.1 实现代码
import timeclass PerformanceAnalyzer:def __init__(self, p):self.p = pdef analyze_performance(self, a_values):performance_data = {}for a in a_values:start_time = time.time()ts = TonelliShanks(self.p)ts.tonelli_shanks(a)elapsed_time = time.time() - start_timeperformance_data[a] = elapsed_timereturn performance_data# 示例
p = 11
a_values = [3, 4, 5, 6, 7, 8]
analyzer = PerformanceAnalyzer(p)
performance_results = analyzer.analyze_performance(a_values)print("Tonelli-Shanks算法性能分析:")
for a, elapsed in performance_results.items():print(f"a={a}: 计算时间 = {elapsed:.6f}秒")

三、Tonelli-Shanks算法的应用领域

Tonelli-Shanks算法在数学和计算机科学中有广泛的应用,主要包括:

  1. 数论:用于寻找模平方根,解决相关的数论问题。
  2. 密码学:在公钥密码体系(如RSA和Diffie-Hellman)中,用于处理模运算。
  3. 计算机视觉:在某些图像处理和计算机视觉算法中,模平方根的计算也可能用到。

四、结论

本文详细介绍了Tonelli-Shanks算法及其在Python中的实现,通过多个实例演示了其应用。我们采用了面向对象的方法,使得代码结构清晰且易于扩展。Tonelli-Shanks算法在数学和计算机科学中具有重要意义,是解决模平方根问题的有效工具。

希望这篇文章能够帮助你更好地理解Tonelli-Shanks算法,并在实际项目中加以应用。如果你有任何问题或建议,欢迎随时交流!

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

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

相关文章

日志代码编写

&#x1f30e;日志代码编写 文章目录&#xff1a; 日志代码编写 了解日志 日志编写       日志等级       获取时间信息       获取文件名行号及处理可变参数列表       以宏的形式传参       日志加锁       日志消息输出方式 完整代码 …

告别繁琐统计,一键掌握微信数据

微信数据管理的挑战在数字时代&#xff0c;微信已成为我们日常沟通和商业活动的重要工具。然而&#xff0c;随着微信号数量的增加&#xff0c;手动统计每个账号的数据变得越来越繁琐。从好友数量到会话记录&#xff0c;再到转账和红包&#xff0c;每一项都需要耗费大量的时间和…

【第几小】

题目 代码 //分块可以AC 20个点的块长&#xff0c; sqrt(n)*5#include<bits/stdc.h> using namespace std;int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n; cin>>n;vector<int> a(n1,0);//分块int len sqrt(n)*5; //块长int k (n%len…

详细分析Pytorch中的transpose基本知识(附Demo)| 对比 permute

目录 前言1. 基本知识2. Demo 前言 原先的permute推荐阅读&#xff1a;详细分析Pytorch中的permute基本知识&#xff08;附Demo&#xff09; 1. 基本知识 transpose 是 PyTorch 中用于交换张量维度的函数&#xff0c;特别是用于二维张量&#xff08;矩阵&#xff09;的转置操…

使用Docker构建和部署微服务

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 [TOC] Docker 是一个开源的容器化平台&#xff0c;可以帮助开发者轻松构建、打包和部署应用程序。本文将详细介绍如何使用 Dock…

Python+Appium+Pytest+Allure自动化测试框架-代码篇

文章目录 自动化测试框架工程目录示例测试代码示例结果查看allurepytest编写pytest测试样例的规则pytest conftest.py向测试函数传参 appium启动appium服务代码端通过端口与appium服务通信对设备进行操作在pytest测试用例中调用appium 更多功能 PythonAppiumPytestAllure自动化…

Elasticsearch Interval 查询:为什么它们是真正的位置查询,以及如何从 Span 转换

作者&#xff1a;来自 Elastic Mayya Sharipova 解释 span 查询如何成为真正的位置查询以及如何从 span 查询过渡到它们。 长期以来&#xff0c;Span 查询一直是有序和邻近搜索的工具。这些查询对于特定领域&#xff08;例如法律或专利搜索&#xff09;尤其有用。但相对较新的 …

IoTDB时序数据库使用

简介 Apache IoTDB 是一款低成本、高性能的物联网原生时序数据库。它可以解决企业组建物联网大数据平台管理时序数据时所遇到的应用场景复杂、数据体量大、采样频率高、数据乱序多、数据处理耗时长、分析需求多样、存储与运维成本高等多种问题。 IoTDB官网 1. 连接数据库 官方…

河北冠益荣信科技公司洞庭变电站工程低压备自投装置的应用

摘 要&#xff1a;随着电力需求增长&#xff0c;供电可靠性变得至关重要&#xff0c;许多系统已有多回路供电。备用电源自动投入装置能提升供电可靠性&#xff0c;它能在主电源故障时迅速切换到备用电源。本文介绍的AM5-DB低压备自投装置&#xff0c;为洞庭变电站提供多种供电方…

STM32实现IAP串口升级含源码(HAL库)

文章目录 一. 关于IAP升级二. IAP升级的分类二. IAP升级原理2.1 正常启动流程2.2 IAP启动流程 三. Ymodem协议3.1 传输过程3.2 帧命令3.3 起始帧3.4 数据帧3.5 结束帧 四. IAP代码实现4.1 Boot 程序4.2 App 程序4.3 展示效果 五. Demo源码六. Qt 上位机 一. 关于IAP升级 IAP&am…

【Hello World 】

【Hello World 】! C语言实现C实现Java实现Python实现 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 几乎每一个程序员都是从Hello World!开始自己的程序人生&#xff0c;作为一个初学编程的小朋友&#xff0c;也需要先编程来输出Hello Wo…

LabVIEW程序员赚钱不仅限于上班

LabVIEW程序员拥有多种途径来实现财富增值&#xff0c;而不仅仅局限于传统的全职工作。以下是一些他们可以利用自身技能和专业知识实现更高财务收益的方法&#xff1a; 1. 专注领域的自由职业与合同工作 制造、科研、医疗技术等行业都需要LabVIEW的专业知识。通过自由职业&…

vue3项目中el-tooltip实现内容溢出时再显示,并设置tip的最大宽度

html代码 <el-tooltip :disabled"!textIsOverflow" placement"top"><template #content><div class"tooltip-div">tootip的内容</div></template><div class"textOverflow" ref"textRef"…

文案语音图片视频管理分析系统-视频矩阵

文案语音图片视频管理分析系统-视频矩阵 1.产品介绍 产品介绍方案 产品名称&#xff1a; 智驭视频矩阵深度分析系统&#xff08;SmartVMatrix&#xff09; 主要功能&#xff1a; 深度学习驱动的视频内容分析多源视频整合与智能分类高效视频检索与编辑实时视频监控与异常预警…

HTML 基础标签——分组标签 <div>、<span> 和基础语义容器

文章目录 1. `<div>` 标签特点用途示例2. `<span>` 标签特点用途示例3. `<fieldset>` 标签特点用途示例4. `<section>` 标签特点用途示例5. `<article>` 标签特点用途示例总结HTML中的分组(容器)标签用于结构化内容,将页面元素组织成逻辑区域…

安防被动红外和主动红外

被动红外探测器是依靠被动的吸收热能动物活动时身体散发出的红外热能进行报警的&#xff0c;也称热释红外探头&#xff0c;其探测器本身是不会发射红外线的。 被动红外探测器中有2个关键性元件&#xff0c;一个是菲涅尔透镜&#xff0c;另一个是热释电传感器。**自然界中任何高…

Windows下将网盘挂载到本地使用(Docker+AList+RaiDrive)

文章目录 安装安装Docker安装Alist安装RaiDrive 安装 安装Docker Windows下安装Docker网上有很多教程&#xff0c;也可以参考我写的博客链接 3.1章节 安装Alist 官网 “切换中文”并找到“使用指南” ”安装“–>"使用Docker” 打开cmd执行如下命令启动容器 do…

C语言 | Leetcode C语言题解之第519题随机翻转矩阵

题目&#xff1a; 题解&#xff1a; typedef struct {unsigned long long val;UT_hash_handle hh; } Hash;typedef struct {Hash *hash;int n_rows;int n_cols; } Solution, SL;Solution* solutionCreate(int n_rows, int n_cols) {SL *obj malloc(sizeof(SL));obj->hash …

C++之多态(上)

C之多态 多态的概念 多态(polymorphism)的概念&#xff1a;通俗来说&#xff0c;就是多种形态。多态分为编译时多态(静态多态)和运⾏时多 态(动态多态)&#xff0c;这⾥我们重点讲运⾏时多态&#xff0c;编译时多态(静态多态)和运⾏时多态(动态多态)。编译时 多态(静态多态)主…

EtherCAT转ModbusTCP相关技术

EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 MS-GW15 概述 MS-GW15 是 EtherCAT 和 Modbus TCP 协议转换网关&#xff0c;为用户提供一种 PLC 扩展的集成解决方案&#xff0c;可以轻松容易将 Modbu…