天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 76|回复: 0

C++实现轮转密码机的加解密算法(无密钥)

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
三转轮密码机有慢速、中速、快速三个轮子,加密时:入明文一位,出密文一位,快轮逆时针转动一格,快轮转满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]

 

 

 

 

C++实现轮转密码机的加解密算法(无密钥)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 12:26 , Processed in 0.121008 second(s), 28 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表