|
三转轮密码机有慢速、中速、快速三个轮子,加密时:入明文一位,出密文一位,快轮逆时针转动一格,快轮转满26次即一圈时,中轮子转动一格,中轮转满26圈时,慢轮转动一次。解密过程即为加密的逆过程。
因实验不要求解密时用密钥,故本文不包含密钥相关内容。
CSDN博客中已经有几篇不错的文章给出算法思路,但看了源码部分多少有些不如意,问题有如下几个:直接验证不给交互、对题意理解有偏差、解密功能中判断和回转的顺序错误导致密文超过26位就无法正确解密。
我的源码如下,欢迎批评指正:
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cstring>
using namespace std;
void Turn_wheel(int* wheel_l, int* wheel_r); // 正向转
void Reverse_turn_wheel(int* wheel_l, int* wheel_r);//反向转
void Encrypt(char* cleartext, char* ciphertext, int* slow_wheel_l, int* slow_wheel_r, int* mid_wheel_l, int* mid_wheel_r,
int* fast_wheel_l, int* fast_wheel_r);
void Decrypt(char* ciphertext, char* cleartext, int* slow_wheel_l, int* slow_wheel_r, int* mid_wheel_l, int* mid_wheel_r,
int* fast_wheel_l, int* fast_wheel_r);
int main()
{
int a;
while (true) {
cout << "Please choose the action you want:\n1.Encrypt\t2.Decrypt" << endl;
cin >> a;
// 快、中、慢三个轮子初始状态
int slow_wheel_l[26] = { 24,25,26,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 };
int slow_wheel_r[26] = { 21,3,15,1,19,10,14,26,20,8,16,7,22,4,11,5,17,9,12,23,18,2,25,6,24,13 };
int mid_wheel_l[26] = { 26,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 };
int mid_wheel_r[26] = { 20,1,6,4,15,3,14,12,23,5,16,2,22,19,11,18,25,24,13,7,10,8,21,9,26,17 };
int fast_wheel_l[26] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 };
int fast_wheel_r[26] = { 8,18,26,17,20,22,10,3,13,11,4,23,5,24,9,12,25,16,19,6,15,21,2,7,1,14 };
char*cleartext = new char[128];
char*ciphertext = new char[128];
memset(cleartext, 0, 128);
memset(ciphertext, 0, 128);
switch (a)
{
case 1:
system("cls");
cout << "Please input the string you want to entrypt:" << endl;
cin >> cleartext;
Encrypt(cleartext, ciphertext, slow_wheel_l, slow_wheel_r, mid_wheel_l, mid_wheel_r, fast_wheel_l, fast_wheel_r);
cout << "cipertext:" << endl;
for (int i = 0; i < strlen(ciphertext); i++)
{
cout << ciphertext[i];
}
cout << endl;
break;
case 2:
system("cls");
cout << "Please input the string you want to decrypt:" << endl;
cin >> ciphertext;
Decrypt(ciphertext, cleartext, slow_wheel_l, slow_wheel_r, mid_wheel_l, mid_wheel_r, fast_wheel_l, fast_wheel_r);
cout << "cleartext:" << endl;
for (int i = 0; i <strlen(cleartext); i++)
{
cout << cleartext[i];
}
cout << endl;
break;
default:
system("cls");
break;
}
}
return 0;
}
void Turn_wheel(int* wheel_l, int* wheel_r)
{
int temp = wheel_l[25];
for (int i = 25; i >= 1; i--)
{
wheel_l[i] = wheel_l[i - 1];
}
wheel_l[0] = temp;
temp = wheel_r[25];
for (int i = 25; i >= 1; i--)
{
wheel_r[i] = wheel_r[i - 1];
}
wheel_r[0] = temp;
}
void Reverse_turn_wheel(int* wheel_l, int* wheel_r)
{
int temp = wheel_l[0];
for (int i = 0; i <= 24; i++)
{
wheel_l[i] = wheel_l[i + 1];
}
wheel_l[25] = temp;
temp = wheel_r[0];
for (int i = 0; i <= 24; i++)
{
wheel_r[i] = wheel_r[i + 1];
}
wheel_r[25] = temp;
}
void Encrypt(char* cleartext, char* ciphertext, int* slow_wheel_l, int* slow_wheel_r, int* mid_wheel_l, int* mid_wheel_r,
int* fast_wheel_l, int* fast_wheel_r)
{
// 定义三个转轮的计数器
int count = 0;
// 转轮加密过程
for (int i = 0; i <=strlen(cleartext)-1 ; i++)
{
if ('A' <= cleartext[i] && cleartext[i] <= 'Z')
{
int cur = cleartext[i] - 'A';//确定字符在轮中的位置
cur = slow_wheel_l[cur];
for (int j = 0; j < 26; j++)
{
if (cur == slow_wheel_r[j])
{
cur = mid_wheel_l[j];
break;
}
}
for (int j = 0; j < 26; j++)
{
if (cur == mid_wheel_r[j])
{
cur = fast_wheel_l[j];
break;
}
}
for (int j = 0; j < 26; j++)
{
if (cur == fast_wheel_r[j])
{
cur = j;
break;
}
}
ciphertext[i] = char(cur + 65);
count++;
Turn_wheel(fast_wheel_l, fast_wheel_r);
if (count % 26 == 0&&count!=0)//判断中轮是否要转动
{
Turn_wheel(mid_wheel_l, mid_wheel_r);
if (count % (26 * 26) == 0&&count!=0) // 判断慢转是否要转动
{
Turn_wheel(slow_wheel_l, slow_wheel_r);
}
}
}
}
}
void Decrypt(char* ciphertext, char* cleartext, int* slow_wheel_l, int* slow_wheel_r, int* mid_wheel_l, int* mid_wheel_r,
int* fast_wheel_l, int* fast_wheel_r)
{
int count = 0;
for (int i = 0; i < strlen(ciphertext); i++)//将转轮盘到加密后的状态
{
if ('A' <= ciphertext[i] && ciphertext[i] <= 'Z')
{
count++;
Turn_wheel(fast_wheel_l, fast_wheel_r);
}
}
if (count % 26 == 0&&count!=0)
{
Turn_wheel(mid_wheel_l, mid_wheel_r);
if (count % (26 * 26) == 0&&count!=0)
{
Turn_wheel(slow_wheel_l, slow_wheel_r);
}
}
// 转轮解密过程
for (int i = strlen(ciphertext) - 1; i >=0; i--)
{
if ('A' <= ciphertext[i] && ciphertext[i] <= 'Z')
{
// 判断中、慢转轮是否需要转动,这一步一定要在快轮回转之前
if (count % 26 == 0 && count != 0)
{
Reverse_turn_wheel(mid_wheel_l, mid_wheel_r);
if (count % (26 * 26) == 0 && count != 0)
{
Reverse_turn_wheel(slow_wheel_l, slow_wheel_r);
}
}
Reverse_turn_wheel(fast_wheel_l, fast_wheel_r);//快轮先回转一格再解密
int cur = ciphertext[i] - 'A';
cur = fast_wheel_r[cur];
for (int j = 0; j < 26; j++)
{
if (cur == fast_wheel_l[j])
{
cur = mid_wheel_r[j];
break;
}
}
for (int j = 0; j < 26; j++)
{
if (cur == mid_wheel_l[j])
{
cur = slow_wheel_r[j];
break;
}
}
for (int j = 0; j < 26; j++)
{
if (cur == slow_wheel_l[j])
{
cur = j;
break;
}
}
count--;
cleartext[i] = char(cur + 65);
}
}
}
密码机初始态、输入规定全部大写等细节是按照教材图例来的。代码能力有限,如果只是为了应付交差可以借鉴,想研究的看看算法思路就行了。
[code]原文链接:https://blog.csdn.net/m0_46602880/article/details/105356309[/code] |
|