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实现(模幂算法和欧几里得算法的使用)后附思路的更多相关文章

  1. RSA简介(二)——模幂算法

    RSA最终加密.解密都要用到模乘的幂运算,简称模幂运算. 回忆一下RSA,从明文A到B B=Ae1%N 对B解密,就是 A=Be2%N 其中,一般来说,加密公钥中的e1一般会比较小,取65537居多, ...

  2. Java数据结构与算法之---求两个数的最大公约数(欧几里得算法)

    一个简单的小算法来获取两个数的最大公约数, public class Test { public static void main(String[] args) { long result = gcd ...

  3. Modular_exponentiation模幂运算

    https://en.wikipedia.org/wiki/Modular_exponentiation 蒙哥马利(Montgomery)幂模运算是快速计算a^b%k的一种算法,是RSA加密算法的核心 ...

  4. [技术栈]C#利用Luhn算法(模10算法)对IMEI校验

    1.Luhn算法(模10算法) 通过查看ISO/IEC 7812-1:2017文件可以看到对于luhn算法的解释,如下图: 算法主要分为三步: 第一步:从右边第一位(最低位)开始隔位乘2: 第二步:把 ...

  5. LeetCode算法题-Reverse String II(Java实现)

    这是悦乐书的第256次更新,第269篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第123题(顺位题号是541).给定一个字符串和一个整数k,你需要反转从字符串开头算起的 ...

  6. LeetCode算法题-Reverse String(Java实现)

    这是悦乐书的第205次更新,第217篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第73题(顺位题号是344).编写一个以字符串作为输入并返回字符串的函数.例如: 输入: ...

  7. RSA加密解密,String转PublicKey、PrivateKey;附Base64.JAR

    网络请求的数据需要加密,服务器给的他们那一套在Android一直报错,自己写了一个: package com.cc.common.util; import javax.crypto.Cipher; i ...

  8. 银行卡号码校验算法(Luhn算法,又叫模10算法)

    有时候在网上办理一些业务时有些需要填写银行卡号码,当胡乱填写时会立即报错,但是并没有发现向后端发送请求,那么这个效果是怎么实现的呢. 对于银行卡号有一个校验算法,叫做Luhn算法. 一.银行卡号码的校 ...

  9. 数模常用算法系列Matlab实现-----线性规划

    线性规划的 Matlab 标准形式 线性规划的目标函数可以是求最大值,也可以是求最小值,约束条件的不等号可以是小于号也可以是大于号.为了避免这种形式多样性带来的不便,Matlab 中规定线性 规划的标 ...

随机推荐

  1. Service-Level Agreement (服务水平协议)

    Service-Level Agreement (服务水平协议) SLA是为负载测试场景定义的具体目标.例如,评测脚本中任意数量事务的平均响应时间,可以定义具体的目标或阈值.测试运行结束之后,Load ...

  2. 分布式session解决——Spring-data-redis

    1.如果没有集成shiro来管理session,可以直接使用spring-session 2.若集成了shiro,需要Spring-data-redis (或 shiro-redis) 3.nginx ...

  3. 用Java实现AES加密

    参考内容来自:http://blog.csdn.net/hbcui1984/article/details/5201247 一)什么是AES? 高级加密标准(英语:Advanced Encryptio ...

  4. xls 编码 utf-8

    直接用 Excel 打开 UTF-8 编码的 CSV 文件会导致汉字部分出现乱码.原因是 Excel 以 ANSI 格式打开,不会做编码识别. ==打开 UTF-8 编码的 CSV 文件的方法:1) ...

  5. Android Frameworks的base目录内容分析 “Android Frameworks base”

    Framework文件夹中base目录下文件分类: Android系统结构框架: Android Framework层各文件夹功能分类:

  6. 修改终端terminal

    修改终端路径 显示的颜色 (1)在home目录中,新建 .dircolors: $vi .dircolors 输入下面内容 DIR 00;36 保存退出. (2)在 .bashrc文件中 $vi .b ...

  7. 机器学习方法、距离度量、K_Means

    特征向量 1.特征向量:以人为例,每个元素可能就对应这人的某些方面,这就是特征,例如:身高.年龄.性别.国际....2.特征工程:目的就是将现有数据中可作为信号的特征与那些仅是噪声的特征区分开来:当数 ...

  8. Jmeter学习系列----3 配置元件之计数器

    在做测试时,会遇到一种需求:在大量数据的情况下,数据不能重复或者需要自增,基于这种形式,我们可以考虑使用计数器. 计数器(counter): 计数器配置允许用户配置起始点,最大值和增量. 计数器将从开 ...

  9. HTML入门3

    HTML主要工作在于编辑文本结构和文本内容,也称语义(semantics)以便能够再浏览器正确地显示,下面开始介绍在文本中添加标题,段落,强调语句,创建列表等等 基础:标题和段落 内容结构化会使得阅读 ...

  10. flask之一些凌乱知识点

    本篇导航: session组件 上下文与内置函数 pymysql问题 模版问题 一.session组件 1.session组件简介 flask-session是flask框架的session组件,由于 ...