使用C++实现RSA加密解密
一,RSA简介。
RSA,一种非对称加密方式。是目前为止最有影响力的加密算法之一,而且是第一个同时应用于加密和数字签名的算法。
其原理为:两个大素数相乘容易,但是若想将两个大素数相乘的积再分解为两个原始的素数很难。安全性依赖于大数因式分解的困难性。
使用公钥加密,私钥解密。
二,主要原理。
1,公钥私钥的制作过程:
1,选择两个足够大,且互质的素数,p和q。
2,计算出p,q的积,n。
3,计算出n的欧拉函数n1=(p-1)*(q-1).
4,选取公钥e:选择一个与n1互质的质数,不为n1因子且1<e<n1。
5,计算私钥d:d*e mod n1=1(就是e对于n1的模逆元素)。
得到公钥KN(e,n),私钥KR(d,n).
2,加密解密。
设明文为:M;密文为C。
加密:M^e mod n=C。
解密:C^d mod n=M。
三,简单测试。
加密解密
根据第二步中的步骤,我们可以进行一项简单测试。
1,假设p=3,q=11。
2,n为33。
3,n的欧拉函数n1=20。
4,选取公钥:e=3。
5,计算私钥:d*3%20=1,d=7。
得到了公钥KN:(3,33)私钥:KR(7,33)。
假设密文M=15。
加密:15^3mod33=9;C=9。
解密:9^7mod33=15;解密成功。
四,代码实现。
1,难点。
1,素数。
首先要解决的就是判断所输入的数子是否为素数,使用C++实现代码为:
bool isPrime(int num) {// 首先,检查数字0和1不是素数,因为它们只有1个因数if (num <= 1)return false;// 素数大于1,所以我们从2开始遍历到sqrt(num),如果找到能整除num的因子,则num不是素数for (int i = 2; i <= sqrt(num); ++i) {// 如果num可以被i整除,说明num不是素数if (num % i == 0) // 模运算符%,结果为0表示可以整除return false;}// 如果我们没有找到任何因子,那么num就是素数return true;
}
首先,质数不能为负数。
其次在for循环内使用了sqre函数,sqre函数是计算所输入的值的平方根,要判断一个数是不是质数,只需要判断 2到所获取的数字之间开根号有没有可以整除的数就可以了。
此处使用了一个简单的数学规则,假设数n,我们并不知道它是否为质数,虽然也可以使用穷举法,但过于耗费时间;但如果他不是素数,必然存在除了1和它本身之外的数,假设有两个因数,都比根号n大,这两个因数相乘必然比根号n的二次方大,就比n大。所以,如果在2和根号n之间的整数能整除n,就说明n不是质数,反之则为质数。
2,模反因数运算。
在计算模反因数之前,要先了解模运算。
a/b=c……e。
a是被除数,d是除数,c是商,e是余数;在他们当中,e就是模。
简而言之,模就是取余运算,保证c为整数。
基于上述表达式,模运算表示为:
a mod b=e
模反因数的定义为:d*e mod n1=1(就是e对于n1的模逆元素)
就是d*e的积除以n1的值,余数是1。
使用C++实现:
// 函数用于判断一个数是否与n互质
bool isCoprime(int num, int n) {// 如果num和n的最大公约数为1,则它们互质return gcd(num, n) == 1;
}// 函数用于计算两个数的最大公约数
int gcd(int a, int b) {if (b == 0) {return a;}return gcd(b, a % b);
}// 找到一个最小的与n互质的质数eint e = 2;while (!isPrime(e) || !isCoprime(e, n·1)) {e++;}cout << "找到的最小的与 " << n << " 互质的质数是 " << e << "。" << endl;
2,完整代码。
#include <iostream>
#include <cmath>
using namespace std;// 定义一个函数 isPrime,接收一个整数作为参数
bool isPrime(int num) {// 首先,检查数字0和1不是素数,因为它们只有1个因数if (num <= 1)return false;// 素数大于1,所以我们从2开始遍历到sqrt(num),如果找到能整除num的因子,则num不是素数for (int i = 2; i <= sqrt(num); ++i) {// 如果num可以被i整除,说明num不是素数if (num % i == 0) // 模运算符%,结果为0表示可以整除return false;}// 如果我们没有找到任何因子,那么num就是素数return true;
}
// 找到比 n1 小的最大质数
int findMaxPrimeLessThan(int n1) {for (int i = n1 - 1; i > 1; --i) {if (isPrime(i)) return i;}return -1; // 如果没有找到,返回 -1
}
bool isCoprime(int a, int b) {// 如果num和n的最大公约数为1,则它们互质int gcd(int a, int b);{if (b == 0) {return a;}return gcd(b, a % b);
}
}// 函数用于计算两个数的最大公约数
int gcd(int a, int b) {if (b == 0) {return a;}return gcd(b, a % b);
}
// 扩展欧几里得算法
void extendedEuclidean(int a, int b, int& x, int& y) {if (b == 0) {x = 1;y = 0;return;}int x1, y1;extendedEuclidean(b, a % b, x1, y1);x = y1;y = x1 - (a / b) * y1;
}// 计算模逆
int modInverse(int a, int m) {int x, y;extendedEuclidean(a, m, x, y);return (x % m + m) % m;
}
// 快速幂算法
long long fastPowerMod(long long base, long long exp, long long mod) {long long result = 1;while (exp > 0) {if (exp % 2 == 1) {result = (result * base) % mod;}base = (base * base) % mod;exp /= 2;}return result;
}int main() {char x;cout << "加密/解密(e/d) :";cin >> x;//输入e或d,e表示加密,d表示解密if (x == 'e' || x == 'E') {char a;cout << "是否使用默认密钥?(y/n) :";cin >> a;//输入y或n,y表示使用默认密钥,n表示使用自定义密钥if (a == 'n'||a == 'N') {cout << "请输入两个用于加密的质数: \n";int num1, num2;cout << "请输入第一个质数: ";cin >> num1;cout << "请输入第二个质数: ";cin >> num2;//输入两个数if (isPrime(num1) && isPrime(num2)) {int p = num1;int q = num2;int n1 = (p - 1) * (q - 1);int e = findMaxPrimeLessThan(n1);//寻找ewhile (!isPrime(e) || !isCoprime(e, n1)) {e++;}int d = modInverse(e, n1);int n = p * q;int C;cout <<"n = "<< n << endl;cout <<"请输入要加密的数字(必须小于n): ";cin >> C;long long M = fastPowerMod(C, e, n);cout << "公钥是 (" << e << ", " << n << "),私钥是 (" << d << ", " << n << ")。" << endl;cout << "加密后的数字是 :" << M << endl;} else {cout << "输入的两个数中至少有一个不是素数,请重新输入。" << endl;}} else {cout << "默认密钥已使用." << endl;int p = 3;int q = 5;int n = p * q;int n1 = (p - 1) * (q - 1);int e = 7;int d = 11;int C;cout <<"n = "<< n << endl;cout <<"请输入要加密的数字(必须小于n): ";cout <<"请输入要加密的数字: ";cin >> C;int M = fmod(pow(C, e), n);cout << "加密前的数字是:" << C << endl;cout << "加密后的数字是:" << M << endl;cout << "公钥是 (" << e << ", " << n << "),私钥是 (" << d << ", " << n << ")。" << endl;}
}else if (x == 'd'||x == 'D') {char a;cout << "是否使用默认密钥?(y/n):";cin >> a;if (a == 'n'||a == 'N'){int d, n, C;cout << "请输入私钥 (d, n),中间使用空格分隔: ";cin >> d >> n;cout << "请输入要解密的数字: ";cin >> C; long long M = fastPowerMod(C, d, n);cout << "解密后的数字是 " << M << endl;}else if (a == 'y'||a == 'Y'){int d = 11;int n = 15;int C;cout <<"请输入要解密的数字: ";cin >> C;int M = fmod(pow(C, d), n);cout << "解密后的数字是 " << M << endl;}else {cout << "输入错误,请重新输入" << endl;}
}
else {cout << "输入错误,请重新输入" << endl;
}return 0;
}
这段代码,或者说这个插件,可以进行RSA计算。不仅可以加密,也可以根据密钥进行解密;而且内置了简单的默认加密方式用于学习,而且还可以对加密参数进行手动修改,更改内容也有相应的检测机制。
运行结果为:
1,使用默认密钥:

2,自定义密钥:

相关文章:
使用C++实现RSA加密解密
一,RSA简介。 RSA,一种非对称加密方式。是目前为止最有影响力的加密算法之一,而且是第一个同时应用于加密和数字签名的算法。 其原理为:两个大素数相乘容易,但是若想将两个大素数相乘的积再分解为两个原始的素数很难…...
C++归并与快速
快排 #include<bits/stdc.h> #include<algorithm> using namespace std; void f(int,int); void cl(int,int,int); void q(int,int); int a[211]; int n; int main(){cin>>n;for(int i0;i<n;i){cin>>a[i];}q(0,n-1);for(int i0;i<n;i){cout<…...
金蝶云苍穹踩过的坑(慢慢更新)
IDEA不能用最新版,不然搜不到金蝶的插件。 我用的是2024.1.7/2023.1.7 IDEA里增加金蝶插件库的地址也变了,现在是 https://tool.kingdee.com/kddt/idea-updatePlugins.xml 金蝶云苍穹部署在服务器 MAC本地IDEA调试的时候,登录N次能成功一次…...
AndroidStudio——安卓项目结构与文件介绍
一、AndroidStudio界面 一个安卓项目界面主要由以下几部分组成: 1.菜单栏:位于顶部,基本的各项菜单操作 2.项目结构:通常位于左侧,展示当前项目的目录结构 3.编辑窗口:通常位于中间,可以用于编…...
华为自反ACL实验
一、实验背景 做这个实验的原因是最近公司里上了三台小程序服务器,由于三台服务器的端口都映射出去了,领导要求A网段的三台服务器不能访问内网B,C网段,同时B、C网段内网用户可以访问A段的94、95、96服务器; 也就是PC4\…...
yml和xml分别代表什么
YML 和 XML 是两种不同的数据序列化格式,它们在软件开发和数据交换中有着广泛的应用: YAML (YAML Ain’t Markup Language): YAML 是一种用于数据序列化的人类可读语言。它被设计为易于阅读和编写,特别适合于配置文件。YAML 使用缩进来表示数…...
Qt多线程编程
在Qt中,多线程编程是一个常见的需求,特别是当你需要执行耗时的后台任务而不希望阻塞用户界面时。多线程编程它允许应用程序同时执行多个任务,从而提高性能和响应速度。Qt提供了一套完善的多线程支持,包括线程类(QThrea…...
springboot438校园志愿者管理系统(论文+源码)_kaic
摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统校园志愿者管理系统信息管理难度大,容错率低&…...
PostgreSQL 常用运维SQL整理
一、查询并杀会话 -- 查询会话 select pid,usename,client_addr,client_port,query_start,query,wait_event from pg_stat_activity; -- 杀会话 select pg_terminate_backend(pid号); -- 使用如下命令自动生成杀会话语句 select datid,datname,pid,usesysid,usename,applicat…...
Debezium Oracle CTAS 解析器实现:基于 ANTLR 的 CREATE TABLE AS SELECT 语句解析
Debezium Oracle CTAS 解析器实现:基于 ANTLR 的 CREATE TABLE AS SELECT 语句解析 本文详细介绍了 Debezium Oracle 连接器中如何解析 CREATE TABLE AS SELECT (CTAS) 语句,通过具体的实现代码帮助读者理解 ANTLR 监听器在复杂 SQL 解析中的应用。 文章目录 Debezium Oracle…...
从零开始学docker(五)-可用的docker镜像
最近docker镜像都不能访问,目前亲测可用的docker镜像可用,并拉取mysql测试完成。 [缺点] docker search 查不到镜像的索引列表,只能手动查询索引目录(解决方案在最后)。 linux服务器vim打开镜像文件daemon.json vim /e…...
力扣——322. 零钱兑换
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无限的。 示…...
.Net_比对Json文件是否一致
简介 该方法用于比较两个Json文件是否完全一致,仅考虑内容若两个文件中的内容只是顺序不一致,内容是一样的,那么也代表这两个文件是相等的 实现代码 调用 using CompareJsonFiles;Console.WriteLine(" 输入信息 ");Console.WriteL…...
科研笔记:ARR 与 ACL rolling
1 ARR 介绍 ARR 提供 评审服务 —— 仅限评审 —— 对于提交的论文。评审不会针对特定会议/场所,但评审标准与传统会议的主会场长文或短文提交要求相同(如 ACL 或其他由 ACL 主办的重要会议) 2 提交论文进行 ARR 评审 提交截止日期 每两个…...
【2024】Camunda常用功能基本详细介绍和使用-上 (1)
这里写目录标题 前言一、 介绍基本概念介绍1.BPMN2.Form3.DMN 二、Camunda使用1、下载安装1.1、camunda-modeler:BPMN绘画工具1.2、camunda-bpm-run:web端控制页面 2、创建流程2.1、部署一个基础流程2.2、添加用户任务2.2.1、绑定表单2.2.1.1、Generated…...
用人话讲计算机:Python篇!(十二)正则运算+re模块
目录 一、正则表达式 (1)什么是正则表达式 (2)它的结构及使用 示例: 1.字符 . (←这里有个小点哦) 2.字符 | 3.字符 [ ] 4.字符^ 5.字符\d (3)补充ÿ…...
使用create-react-app创建工程时报错处理
1:全局安装create-react-app npm install -g create-react-app 2:切换到项目要创建的目录下 cd /d G:\vsCode_project\react 3:使用脚手架命令创建工程 create-react-app 项目名 项目名命名要遵循npm包命名规范:数字、小写字…...
C# 探险之旅:第三十五节 - 类型class之抽象类 (Abstract Class) 和 抽象方法 (Abstract Method)
👋 嗨,勇敢的探险家们!欢迎再次踏上C#的神秘之旅。今天,我们要进入一片既神秘又充满无限可能的领域——抽象类与抽象函数的奇幻森林。想象一下,你是一名勇敢的骑士,要在这片森林里寻找传说中的“编程之宝”…...
qt-C++笔记之父类窗口、父类控件、对象树的关系
qt-C笔记之父类窗口、父类控件、对象树的关系 code review! 参考笔记 1.qt-C笔记之父类窗口、父类控件、对象树的关系 2.qt-C笔记之继承自 QWidget和继承自QObject 并通过 getWidget() 显示窗口或控件时的区别和原理 3.qt-C笔记之自定义类继承自 QObject 与 QWidget 及开发方式…...
Cisco Packet Tarcer配置计网实验笔记
文章目录 概要整体架构流程网络设备互连基础拓扑图拓扑说明配置步骤 RIP/OSPF混合路由拓扑图拓扑说明配置步骤 BGP协议拓扑图拓扑说明配置步骤 ACL访问控制拓扑图拓扑说明配置步骤 HSRP冗余网关拓扑图拓扑说明配置步骤 小结 概要 一些环境配置笔记 整体架构流程 网络设备互连…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
