RSA算法的C++string实现(模幂算法和欧几里得算法的使用)后附思路
void resetNumA(string numAStr);
//使用string重置numB
void resetNumB(string numBStr);
//将数组转换为字符串,用于输出
string getNumString(int* num);
//判断两个数字哪个大
int compare(string numAStr, string numBStr);
//加法
string sum(string numAStr, string numBStr);
//减法
string sub(string numAStr, string numBStr);
//乘法
string mul(string numAStr, string numBStr);
//除
string div(string numAStr, string numBStr);
//取余
string mod(string numAStr, string numBStr);
//模幂算法
string getMod(string m, string pow, string n);
//求2的n次方函数
string mul_2(int i);
//求m的n次方
string mul_m(string m, string n);
#endif
#include<iostream>
#include"operation.h"
#include<string>
#include<vector>
using namespace std; //结果支持的最大位数
const static int M = ; int numA[M];
int numB[M]; //使用string重置numA
void resetNumA(string numAStr)
{
memset(numA, , M * sizeof(int)); //将字符串的每一位都转换成数字传入数组
for (int i = ; i < numAStr.length(); i++)
{
numA[i] = numAStr[numAStr.length() - i - ] - '';
}
} //使用string重置numB
void resetNumB(string numBStr)
{
memset(numB, , M * sizeof(int)); //将字符串的每一位都转换成数字传入数组
for (int i = ; i < numBStr.length(); i++)
{
numB[i] = numBStr[numBStr.length() - i - ] - '';
}
} //将数组转换为字符串,用于输出
string getNumString(int* num)
{
string numString;
bool isBegin = false;
for (int i = M - ; i >= ; i--)
{
if (num[i] != )
{
isBegin = true;
} if (isBegin)
{
numString += num[i] + '';
}
}
return numString;
} //判断两个数字哪个大
int compare(string numAStr, string numBStr)
{
int i = ;
int la = ;
while (numAStr[i] == '') {
la++;
i++;
}
i = ;
int lb = ;
while (numBStr[i] == '') {
lb++;
i++;
}
string a(numAStr.substr(la, numAStr.length()));
string b(numBStr.substr(lb, numBStr.length()));
if (a.length() > b.length())
{
return ;
}
else if (a.length() < b.length())
{
return -;
}
else
{
for (int i = ; i < a.length(); i++)
{
if (a[i]>b[i])
{
return ;
} if (a[i]<b[i])
{
return -;
}
}
return ;
}
} //加法
string sum(string numAStr, string numBStr)
{
resetNumA(numAStr);
resetNumB(numBStr); for (int i = ; i < M; i++)
{
//结果保存在numA中
numA[i] += numB[i]; //数字大于9则进位
if (numA[i]>)
{
numA[i] -= ;
numA[i + ]++;
}
} return getNumString(numA);
} //减法
string sub(string numAStr, string numBStr)
{
bool isNegative = false; //如果numA比numB小
//则结果为负数
//调换位置进行计算
if (compare(numAStr, numBStr) == -)
{
isNegative = true;
string temp = numAStr;
numAStr = numBStr;
numBStr = temp;
}
else if (compare(numAStr, numBStr) == )
{
return "";
} resetNumA(numAStr);
resetNumB(numBStr); for (int i = ; i < M; i++)
{
//减数小于被减数就借位
if (numA[i]<numB[i])
{
numA[i] = numA[i] + - numB[i];
numA[i + ]--;
}
else
{
numA[i] -= numB[i];
}
}
if (isNegative)
{
return "-" + getNumString(numA);
}
else
{
return getNumString(numA);
} } //乘法 string mul(string numAStr, string numBStr)
{
resetNumA(numAStr);
resetNumB(numBStr); vector<string> nums;
for (int i = ; i < numBStr.length(); i++)
{
//初始化一个临时数据来保存被乘数与乘数的某一位相乘的结果
int temp[M];
memset(temp, , M * sizeof(int)); for (int j = i; j < numAStr.length() + i; j++)
{
temp[j] += numA[j - i] * numB[i] % ; temp[j + ] = numA[j - i] * numB[i] / ; //如果大于9,那么就做进位处理
if (temp[j]>)
{
temp[j] -= ;
temp[j + ]++;
}
}
nums.push_back(getNumString(temp));
} //每位相乘的结果再用加法加起来
string result = nums[];
for (int i = ; i < nums.size(); i++)
{
result = sum(result, nums[i]);
} return result;
} //除,结果精确到个位
string div(string numAStr, string numBStr)
{
resetNumA(numAStr);
resetNumB(numBStr); string result;
string left; if (compare(numAStr, numBStr) == -)
{
return "";
} //标记第一个不为0的位数的出现
bool flag = false;
for (int i = ; i < numAStr.length(); i++)
{
left += numAStr[i]; //余数比除数大
if (compare(left, numBStr) == )
{
flag = true; int count = ;
string temp = numBStr; while (true)
{
//每循环一次加上一个余数
temp = sum(temp, numBStr); //余数仍然大于除数,继续累加
if (compare(left, temp) == )
{
count++;
}
//余数小于除数
//可以计算结果
else if (compare(left, temp) == -)
{
result += count + '';
left = sub(left, sub(temp, numBStr));
break;
}
//此时余数刚好是除数的倍数
else if (compare(left, temp) == )
{
count++;
result += count + '';
left = "";
break;
}
}
}
//刚好除尽
else if (compare(left, numBStr) == )
{
flag = true;
result += "";
left = "";
}
//余数比除数小,跳到下一位
else if (flag)
{
result += "";
} } return result;
}
//取模
string mod(string numAStr, string numBStr)
{ string result = ""; if (compare(numAStr, numBStr) == -)
{
return numAStr;
}
else if (compare(numAStr, numBStr) == ) {
return result;
}
else {
string d = div(numAStr, numBStr);
string x = mul(numBStr, d);
result = sub(numAStr, x);
return result;
}
} //加密解密模幂算法
string getMod(string m, string pow, string n)
{
string temp;
while (compare(pow,"") == ) {
if(mod(pow,"")=="")
temp = temp + "";
else
temp = temp + "";
pow = div(pow,"");
}
temp = temp + "";
int length = temp.length();
string T[M];
string M = "";
T[] = mod(m, n);
for (int i = ; i < length; i++) {
T[i] = mod(mul(T[i-],T[i-]),n);
}
for (int i = ; i < length; i++) {
if (temp[i] == '') {
M = mul(M, T[i]);
}
}
string result = mod(M, n);
return result;
} //求2的n次方函数
string mul_2(int i) {
string result = "";
for (int j = ; j < i; j++) {
result = mul(result, "");
}
if (i == )
return "";
else
return result;
} //求m的t次方函数
string mul_m(string m,string t) {
string result = m;
string j;
for ( j = ""; compare(j, t) == -; j = sum(j, "")) {
result = mul(result, m);
}
return result;
}
#include<iostream>
#include"operation.h"
using namespace std; int main() {
string char_number_p;
string char_number_q; string temp[][];
//p=17,q=11
//p=17,q=19
//p=41,q=43
//67,71
//797 809
//49993 49999
//116747 110221
//1000017077
//
char_number_p="";
char_number_q=""; string n = mul(char_number_p, char_number_q);
string tmp1 = "";
string On = mul(sub(char_number_p, tmp1),sub(char_number_q, tmp1)); string e = ""; //拓展欧几里得算法
temp[][] = e;
temp[][] = "";
temp[][] = On;
temp[][] = "";
int i = ;
do {
temp[i][] = temp[i - ][];
temp[i][] = "";
temp[i][] = temp[i - ][];
temp[i][] = "";
if (compare(temp[i][], temp[i][]) == ) {
temp[i][] = mod(temp[i][], temp[i][]);
}
else {
temp[i][] = mod(temp[i][], temp[i][]);
}
i++;
} while (compare(temp[i - ][], "") == );
int value = i - ;
temp[value][] = "";
value--;
while (value >= ) {
if (temp[value + ][] != "")
temp[value][] = div(sub(mul(temp[value][], temp[value + ][]), ""), temp[value][]);
else if (temp[value + ][] != "")
temp[value][] = div(sum(mul(temp[value][], temp[value + ][]), ""), temp[value][]);
value--;
}
string d = temp[][]; cout << "e:" << e << endl;
cout << "p*q:" << n << endl;
cout << "O(n):" << On << endl;
cout << "d:" << d << endl;
cout << "密钥{ " << e << " , " << n << " }" << endl;
cout << "公钥{ " << d << " , " << char_number_p <<" , "<< char_number_q << " }" << endl; string miwen;
cout << "请输入密文(暂小于10的29次方)" << endl;
cin >> miwen;
cout << "密文:" << miwen << endl;
string C1 = getMod(miwen, e, n);
cout << "加密后的明文:" << C1 << endl;
string M1 = getMod(C1, d, n);
cout << "解密后的密文:" << M1 << endl; cout << "请输入密文(暂小于10的29次方)" << endl;
cin >> miwen;
string C2 = getMod(miwen, e, n);
cout << "加密后的明文:" << C2 << endl;
string M2 = getMod(C2, d, n);
cout << "解密后的密文:" << M2 << endl; cout << "请输入密文(暂小于10的29次方)" << endl;
cin >> miwen;
string C3 = getMod(miwen, e, n);
cout << "加密后的明文:" << C3 << endl;
string M3 = getMod(C3, d, n);
cout << "解密后的密文:" << M3 << endl; system("pause");
return ;
}
以上为测试实现的代码。
思路:先实现string类型的加减乘除的重写,以及用到的其他的操作函数,比较,取模,加解密函数,以及其他的m的n次方的操作。
然后在主函数里面嵌入欧几里得算法,调用求得d,之后就是简单的调用加解密函数
pq的值也是测试得到的
这是运行截图:
//拓展欧几里得算法
temp[0][0] = e;
temp[0][1] = "";
temp[0][2] = On;
temp[0][3] = "";
int i = 1;
do {
temp[i][0] = temp[i - 1][0];
temp[i][1] = "";
temp[i][2] = temp[i - 1][2];
temp[i][3] = "";
if (compare(temp[i][0], temp[i][2]) == 1) {
temp[i][0] = mod(temp[i][0], temp[i][2]);
}
else {
temp[i][2] = mod(temp[i][2], temp[i][0]);
}
i++;
} while (compare(temp[i - 1][0], "1") == 1);
int value = i - 1;
temp[value][1] = "1";
value--;
while (value >= 0) {
if (temp[value + 1][1] != "")
temp[value][3] = div(sub(mul(temp[value][0], temp[value + 1][1]), "1"), temp[value][2]);
else if (temp[value + 1][3] != "")
temp[value][1] = div(sum(mul(temp[value][2], temp[value + 1][3]), "1"), temp[value][0]);
value--;
}
string d = temp[0][1];
这部分拓展的欧几里得算法也可以单独使用,这里是用空间换取的时间效率。
RSA算法的C++string实现(模幂算法和欧几里得算法的使用)后附思路的更多相关文章
- RSA简介(二)——模幂算法
RSA最终加密.解密都要用到模乘的幂运算,简称模幂运算. 回忆一下RSA,从明文A到B B=Ae1%N 对B解密,就是 A=Be2%N 其中,一般来说,加密公钥中的e1一般会比较小,取65537居多, ...
- Java数据结构与算法之---求两个数的最大公约数(欧几里得算法)
一个简单的小算法来获取两个数的最大公约数, public class Test { public static void main(String[] args) { long result = gcd ...
- Modular_exponentiation模幂运算
https://en.wikipedia.org/wiki/Modular_exponentiation 蒙哥马利(Montgomery)幂模运算是快速计算a^b%k的一种算法,是RSA加密算法的核心 ...
- [技术栈]C#利用Luhn算法(模10算法)对IMEI校验
1.Luhn算法(模10算法) 通过查看ISO/IEC 7812-1:2017文件可以看到对于luhn算法的解释,如下图: 算法主要分为三步: 第一步:从右边第一位(最低位)开始隔位乘2: 第二步:把 ...
- LeetCode算法题-Reverse String II(Java实现)
这是悦乐书的第256次更新,第269篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第123题(顺位题号是541).给定一个字符串和一个整数k,你需要反转从字符串开头算起的 ...
- LeetCode算法题-Reverse String(Java实现)
这是悦乐书的第205次更新,第217篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第73题(顺位题号是344).编写一个以字符串作为输入并返回字符串的函数.例如: 输入: ...
- RSA加密解密,String转PublicKey、PrivateKey;附Base64.JAR
网络请求的数据需要加密,服务器给的他们那一套在Android一直报错,自己写了一个: package com.cc.common.util; import javax.crypto.Cipher; i ...
- 银行卡号码校验算法(Luhn算法,又叫模10算法)
有时候在网上办理一些业务时有些需要填写银行卡号码,当胡乱填写时会立即报错,但是并没有发现向后端发送请求,那么这个效果是怎么实现的呢. 对于银行卡号有一个校验算法,叫做Luhn算法. 一.银行卡号码的校 ...
- 数模常用算法系列Matlab实现-----线性规划
线性规划的 Matlab 标准形式 线性规划的目标函数可以是求最大值,也可以是求最小值,约束条件的不等号可以是小于号也可以是大于号.为了避免这种形式多样性带来的不便,Matlab 中规定线性 规划的标 ...
随机推荐
- day12.生成器;wraps初识
生成器 在 Python 中,使用了 yield 的函数被称为生成器(generator). 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器. 在 ...
- Tomcat目录结构详解
1.bin: 该目录下存放的是二进制可执行文件,如果是安装版,那么这个目录下会有两个exe文件:tomcat6.exe.tomcat6w.exe,前者是在控制台下启动Tomcat,后者是弹出UGI窗口 ...
- 阿里云服务器端配置TensorFlow & jupyter
在阿里云上搭建爬取某信的公众号文章的程序时,发现需要验证码验证,技穷之后考虑做一个验证码识别程序,所以开始在服务器上搭建机器学习平台,背景,服务器上已经有其他应用在跑着了,所以不想停服,初始环境:ce ...
- vscode断点调试本地客户端文件
一.安装chrome,安装vscode,打开vscode编辑器,安装插件Debugger for Chrome 二.新建文件 1.目录结构 . ├── index.html ├── index.js ...
- 错误解决记录-------------验证启动HDFS时遇到的错误
主要解决验证启动HDFS时: 1) jps:bash: jps: command not found... 原因:主要是java/bin 环境变量没配置好. 解决办法: 在 ~/.bash_prof ...
- 2017-2018 ACM-ICPC, Central Europe Regional Contest (CERC 17)
A. Assignment Algorithm 按题意模拟即可. #include<stdio.h> #include<iostream> #include<string ...
- LeetCode Monotone Stack Summary 单调栈小结
话说博主在写Max Chunks To Make Sorted II这篇帖子的解法四时,写到使用单调栈Monotone Stack的解法时,突然脑中触电一般,想起了之前曾经在此贴LeetCode Al ...
- css 控制文字显示两行,多余用省略号 手机端
p { width:100px; position:relative; line-height:20px; /*行高为高度的一半,这样就是两行*/ height:40px; overflow:hidd ...
- laravel之模型Model
模型Model: 在控制器中调用:
- maven和glassfish安装和部署及hello1和hello2的部署
1.安装maven和glassfish及配置环境变 首先搜索并下载maven3.6.0和glassfish4.1.1(版本看按需要选择). 点击安装包进行安装 安装完成后开始配置环境变量 打开系统环境 ...