古典密码算法的设计与实现(C++实现)

编写实现古典密码的程序,能对给定的明文或密文进行正确的加密和解密。

(1) 仿射密码

参数选取:模数n=26+10=36,k2为学号后2位;k1为与学号后2位最近的素数。

加解密:加密自己名字的全拼和学号,再解密。
加密代码:

#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
    /*
    (1)    仿射密码
    参数选取:模数n=26+10=36,k2为学号后2位;k1为与学号后2位最近的素数。
    加解密:加密自己名字的全拼和学号,再解密。
    */
    int n = 36;
    string m, c;
    int buff[32], len = 0, k1 = 0, k2 = 0;
    cout << "输入明文:" << endl;
    cin >> m;
    cout << "输入k1:";
    cin >> k1;
    cout << "输入k2:";
    cin >> k2;
    //把明文转化成10进制整数,0-9,a-z分别代表十进制0-36
    for (int i = 0; m[i] != '\0'; i++)
    {
        //字母转10进制整数
        if (m[i] > '9')
            buff[i] = m[i] - 87;
        else
            buff[i] = m[i] - 48;//0ASCII为48
        len++;
    }
    //加密运算,C=k1*m+k2 mod n;
    for (int i = 0; i < len; i++)
    {
        buff[i] = (buff[i] * k1 + k2) % n;
    }
    //把数字对应为密文空间内的字符
    for (int i = 0; i < len; i++)
    {
        if (buff[i] < 10)
            m[i] = buff[i] + 48;
        else
            m[i] = buff[i] + 87;

    }
    cout << "密文为:" << endl;
    for (int i = 0; i<len; i++)
    {
        cout << m[i];
    }
    cout << endl;
    //解密,M=(C-k2)*k1^(-1)
    system("pause");
    return 0;
}

这里写图片描述
解密代码:

#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
//求解x^(-1)mod p
int GetIne(int x, int p)
{
    for (int i = 0; i<p; i++)
    {
        if (x*i%p == 1)
        {
            x = i;
            break;
        }
    }
    return x;
}
int main()
{
    /*
    (1) 仿射密码
    参数选取:模数n=26+10=36,k2为学号后2位;k1为与学号后2位最近的素数。
    加解密:加密自己名字的全拼和学号,再解密。
    */
    int n = 36;
    string m, c;
    int buff[32], len = 0, k1 = 0, k2 = 0, k = 0;
    cout << "输入密文:" << endl;
    cin >> m;
    cout << "输入k1:";
    cin >> k1;
    cout << "输入k2:";
    cin >> k2;
    //把明文转化成10进制整数,0-9,a-z分别代表十进制0-36
    //解密,M=(C-k2)*k1^(-1)
    for (int i = 0; m[i] != '\0'; i++)
    {
        //字母转10进制整数
        if (m[i] > '9')
            buff[i] = m[i] - 87;
        else
            buff[i] = m[i] - 48;//0ASCII为48
        len++;
    }
    //解密运算,M=(C-k2)*k1^(-1)
    k = GetIne(k1, n);
    for (int i = 0; i < len; i++)
    {
        buff[i] = ((buff[i] - k2)*k) % n;
        if (buff[i] < 0)
            buff[i] += n;
        //buff[i] = (buff[i] * k1 + k2) % n;
    }
    //把数字对应为明文空间内的字符
    for (int i = 0; i < len; i++)
    {
        if (buff[i] < 10)
            m[i] = buff[i] + 48;
        else
            m[i] = buff[i] + 87;

    }
    cout << "明文为:" << endl;
    for (int i = 0; i<len; i++)
    {
        cout << m[i];
    }
    cout << endl;
    system("pause");
    return 0;
}

这里写图片描述
(2) 置换密码

参数选取:分组长度为7;置换关系随机选取;

加解密:加密自己名字的全拼和学号(长度不足时后面全补填充长度),再解密。
加密代码:

/*置换密码
参数选取:分组长度为7;置换关系随机选取;
加解密:加密自己名字的全拼和学号(长度不足时后面全补
填充长度),再解密。
string中的函数:
swap()--交换字符
push_back() --插入字符
*/
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
    string m;
    system("title = 加密");
    cout << "输入明文:" << endl;
    cin >> m;

    //cout << "string长度:" << m.size()<<endl;
    遍历明文
    //for (int i=0;m[i]!='\0';i++)
    //{
    //  cout << m[i];
    //}
    //cout << endl;
    //如果明文不足7的倍数就填字符A
    for (int i = m.size(); i % 7 != 0; i++)
    {
        m.push_back('A'); //在字符串后面插入字符A
    }
    //cout << "string长度:" << m.size() << endl;
    遍历
    //for (int i = 0;i<m.size(); i++)
    //{
    //  cout << m[i];
    //}
    //加密
    for (int i = 0; i < m.size(); i += 7)
    {
        swap(m[i], m[i + 2]);//f(1) 
        swap(m[i], m[i + 6]);//f(2) 
        swap(m[i], m[i + 3]);//f(3) 
        swap(m[i], m[i + 0]);//f(4) 
        swap(m[i], m[i + 5]);//f(5) 
        swap(m[i], m[i + 1]);//f(6) 
        swap(m[i], m[i + 4]);//f(7) 
    }
    //输出密文
    cout << "密文为:" << endl;
    for (int i = 0; i<m.size(); i++)
    {
        if (i != 0 && i % 7 == 0)
            cout << endl;
        cout << m[i];
    }
    cout << endl;
    system("pause");
    return 0;
}

这里写图片描述
解密代码:

/*置换密码
参数选取:分组长度为7;置换关系随机选取;
加解密:加密自己名字的全拼和学号(长度不足时后面全补
填充长度),再解密。
string中的函数:
swap()交换字符
push_back()插入字符
*/
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
    string m;
    cout << "输入密文:" << endl;
    cin >> m;
    system("title = 解密");
    //cout << "string长度:" << m.size()<<endl;
    遍历明文
    //for (int i=0;m[i]!='\0';i++)
    //{
    //  cout << m[i];
    //}
    //cout << endl;
    //cout << "string长度:" << m.size() << endl;
    遍历
    //for (int i = 0;i<m.size(); i++)
    //{
    //  cout << m[i];
    //}
    //解密
    for (int i = 0; i < m.size(); i += 7)
    {
        swap(m[i], m[i + 4]);//f(7)
        swap(m[i], m[i + 1]);//f(6)
        swap(m[i], m[i + 5]);//f(5) 
        swap(m[i], m[i + 0]);//f(4)
        swap(m[i], m[i + 3]);//f(3) 
        swap(m[i], m[i + 6]);//f(2) 
        swap(m[i], m[i + 2]);//f(1) 
    }
    //输出明文
    cout << "明文为:" << endl;
    for (int i = 0;m[i] != 'A'; i++)
    {
        /*if (i != 0 && i % 7 == 0)
        cout << endl;*/
        cout << m[i];
    }
    cout << endl;
    system("pause");
    return 0;
}

这里写图片描述
(3) Hill密码 (例1.7)
加密代码:

#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
    string m;
    int buffer[4];
    int a[4];//存放m*A mod 26的结果
    int b[16];//存放m和A的转置矩阵的乘积
              //矩阵A的转置矩阵
    int A[] = { 8,6,5,10,
        6,9,8,6,
        9,5,4,11,
        5,10,9,4 };
    A的逆矩阵的转置矩阵
    //int B[] = { 23,2,2,25,
    //  20,11,20,2,
    //  5,18,6,22,
    //  1,1,25,25 };
    cout << "输入明文:" << endl;
    cin >> m;
    system("title = 加密");
    //把字符转化成10进制整数
    for (int i = 0; m[i] != '\0'; i++)
    {
        buffer[i] = m[i] - 97;
    }

    cout << "buffer数组中的元素:" << endl;
    for (int i = 0; i<4; i++)
    {
        cout << buffer[i] << ",";
    }
    cout << endl;
    //加密C = m * A mod 26,把结果放入数组a
    for (int i = 0; i<16; i++)
    {
        b[i] = buffer[i % 4] * A[i];
    }
    cout << "b数组中的元素:" << endl;
    for (int i = 0; i<16; i++)
    {
        cout << b[i] << ",";
    }
    cout << endl;
    for (int i = 0; i < 16; i += 4)
    {
        a[i / 4] = (b[i] + b[i + 1] + b[i + 2] + b[i + 3]) % 26;
        if (a[i / 4] < 0)
            a[i / 4] += 26;
    }

    cout << "a数组中的元素:" << endl;
    for (int i = 0; i<4; i++)
    {
        cout << a[i] << ",";
    }
    cout << endl;
    //转换为字符
    cout << "密文为:" << endl;
    for (int i = 0; i<4; i++)
    {
        m[i] = a[i] + 97;
        cout << m[i];
    }
    cout << endl;
    system("pause");
    return 0;
}

这里写图片描述
解密代码:

#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
    string m;
    int buffer[4];
    int a[4];
    int b[16];//存放m和A的转置矩阵的乘积
              //矩阵A的转置矩阵
    /*int A[] = { 8,6,5,10,
        6,9,8,6,
        9,5,4,11,
        5,10,9,4 };*/
    //A的逆矩阵的转置矩阵
    int B[] = { 23,2,2,25,
        20,11,20,2,
        5,18,6,22,
        1,1,25,25 };
    cout << "输入密文:" << endl;
    cin >> m;
    system("title = 解密");
    //把字符转化成10进制整数
    for (int i = 0; m[i] != '\0'; i++)
    {
        buffer[i] = m[i] - 97;
    }

    cout << "buffer数组中的元素:" << endl;
    for (int i = 0; i<4; i++)
    {
        cout << buffer[i] << ",";
    }
    cout << endl;
    //解密M = C * B mod 26,把结果放入数组a,B是A的逆矩阵
    for (int i = 0; i<16; i++)
    {
        b[i] = buffer[i % 4] * B[i];
    }
    cout << "b数组中的元素:" << endl;
    for (int i = 0; i<16; i++)
    {
        cout << b[i] << ",";
    }
    cout << endl;
    for (int i = 0; i < 16; i += 4)
    {
        a[i / 4] = (b[i] + b[i + 1] + b[i + 2] + b[i + 3]) % 26;
        if (a[i / 4] < 0)
            a[i / 4] += 26;
    }

    cout << "a数组中的元素:" << endl;
    for (int i = 0; i<4; i++)
    {
        cout << a[i] << ",";
    }
    cout << endl;
    //转换为字符
    cout << "明文为:" << endl;
    for (int i = 0; i<4; i++)
    {
        m[i] = a[i] + 97;
        cout << m[i];
    }
    cout << endl;
    system("pause");
    return 0;
}

这里写图片描述

古典加密算法有多种,例如凯撒密码、维吉尼亚密码、栅栏密码等。这里我们选择凯撒密码进行介绍和编程实现。 凯撒密码是一种最简单和最广为人知的替换加密技术,它通过将字母在字母表中向左或向右移动固定数目来进行加密。例如,如果移动的数目是3,那么'A'将被替换为'D','B'变为'E',以此类推。解密则是将字母向相反方向移动相同的数目。 以下是一个简单的凯撒密码的加密和解密的Python代码实现: ```python def caesar_encrypt(text, shift): encrypted_text = "" for char in text: if char.isalpha(): # 检查字符是否为字母 shift %= 26 # 确保移位在0-25之间 if char.islower(): offset = ord('a') else: offset = ord('A') encrypted_text += chr((ord(char) - offset + shift) % 26 + offset) else: encrypted_text += char # 非字母字符保持不变 return encrypted_text def caesar_decrypt(encrypted_text, shift): return caesar_encrypt(encrypted_text, -shift) # 使用凯撒密码加密和解密 original_text = "Hello, World!" shift_amount = 3 encrypted = caesar_encrypt(original_text, shift_amount) print("加密后的文本:", encrypted) decrypted = caesar_decrypt(encrypted, shift_amount) print("解密后的文本:", decrypted) ``` 在这个代码中,`caesar_encrypt` 函数负责加密文本,而`caesar_decrypt` 函数实际上调用了`caesar_encrypt` 函数并传递了负的移位数来解密文本。这段代码还处理了非字母字符,确保它们在加密和解密过程中保持不变。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值