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 中规定线性 规划的标 ...
随机推荐
- windows下创建MySQL定时备份与删除脚本
今天在windows服务器上面写了一个MySQL定时任务,备份呢与删除 rem *****************************Code start********************* ...
- gitLib操作笔录《一》:创建分支,切换分支,提交分支到远程,以及基本代码clone与更新提交到远程操作指令
git 操作经验注:master表示的是主线,origin 表示远程源 创建分支:git checkout -b < branch_name >或 < master >切换分支 ...
- hdu4791-Alice's Print Service
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4791 题目解释:给你一组数据s1,p1,s2,p2...sn,pn,一个数字q,问你当要打印q张资料时 ...
- 【Spring Boot】关于上传文件例子的剖析
目录 Spring Boot 上传文件 功能实现 增加ControllerFileUploadController 增加ServiceStorageService 增加一个Thymeleaf页面 修改 ...
- windows控件理论学习
mmp快考试了还在浪 一.对话框编辑器创建控件 1.使用new在堆上创建,系统结束时我们需要使用delete去销毁控件 2.对话框编辑器控件,程序结束,自动销毁 二.控件类的基类 CWnd类和消息映射 ...
- day14_dom操作
1.input的类型typy=(text/password/button/submit/checkbox/radioreset/file) 一.参考:http://www.imdsx.cn/index ...
- python 生成器generator
关于生成器,主要有以下几个 关键点的内容 一.什么是generator ,为什么要有generator? 二.两种创建生成器方式 三.yield关键字 四.generator 两个调用方法 next( ...
- 解决国内NPM安装依赖速度慢问题
版权声明:本文为博主原创文章,转载请注明原文地址. http://blog.csdn.net/rongbo_j/article/details/52106580 不知道各位是否遇到这种情况,使用N ...
- jQuery效果-----fadeIn()、fadeOut()、fadeToggle()、fadeTo()
fadeIn(),fadeOut(),fadeToggle(),fadeTo() fadeIn()-----淡入已经隐藏的元素(把隐藏的被选元素渐渐显示出来). 语法:$(selector).fade ...
- Java中的常用集合类型总结
1.可重复列表(List) LinkedList和ArrayList的区别:http://www.importnew.com/6629.html ArrayList vs. LinkedList vs ...