古典密码算法

古典密码算法曾被广泛应用,大都比较简单,使用手工和机械操作来实现加密和解密。

一、替代密码

  替代密码算法的原理是使用替代法进行加密,就是对明文中的字符用其他字符替代后形成密文。例如,明文字母 a, b, c, d, 用 d, e, f , g 做对应替换后形成密文。替代密码包括多种类型,如单表替代密码,多表替代密码,多字母替代密码等。凯撒(Caesar)密码是一种典型的单表替代密码。它的加密方法是将明文中的每个字母用此字符在字母表中后面的第 k 个字母替代。它的加密过程可以表示为下面的函数:

E ( k ) = ( m + k ) m o d n E\left ( k\right )=\left ( m+k \right )mod n E(k)=(m+k)modn

  其中,m 为明文字母在字母表中的位置数,n 为字母表中的字母个数,k 为密钥,E(k)为密文字母在字母表中对应的位置数。
  解密过程类推。

二、置换密码

  置换密码算法的原理是不改变明文字符,只将字符在明文中的排列顺序改变,从而实现明文信息的加密。置换密码也叫换位密码。
  它的加密方法是将明文中的字母按照给定的顺序安排在一个矩阵中,然后用根据密钥提供的顺序重新组合矩阵中的字母,形成密文。例如,明文为 attack begins at five,密钥为 cipher,将明文按照每行 6 个字母的形式排在矩阵中,如下形式:

a t t a c k
b e g i n s
a t f i v e
  根据密钥 cipher 中各字母在字母表中出现的先后顺序,给定一个置换:
古典密码算法_第1张图片
  根据上面的置换,将原有矩阵中的字母按照第 1、4、5、3、2、6 的顺序排列,则有下 列形式:
a a c t t k
b i n g e s
a i v f t e
  从而得到密文:**aacttkbingesaivfte**

  解密过程类推。

三、代码思路

  替代密码没什么好说的,就是根据ASCII码表来设计的,这里我没有对大写的进行考虑。
  置换密码根据字符串长度转换为一个6*n的矩阵,如果长度不为6的整数,则在最后一行尾部用空格补齐。

#include 
#include 
#include 
#include 
using namespace std;

constexpr auto column = 6;
constexpr auto Encrypt = 0;
constexpr auto Decrypt = 1;

/*凯撒算法*/
string Caesar(string str, int num,int mode)
{
	//加密算法
	if (mode == Encrypt) {
		for (int i = 0; i < str.length(); ++i) {
			str[i] = (str[i] - 'a' + num) % 26 + 'a';
		}
		cout << "加密完成!" << endl;
	}
	//解密算法
	else if (mode == Decrypt) {
		for (int i = 0; i < str.length(); ++i) {
			str[i] = (str[i] - 'a' + (26 - num)) % 26 + 'a';
		}
		cout << "解密完成!" << endl;
	}
	return str;
}

/*置换算法*/
string Permute(string str, int cipher,int mode) {
	int num = 0;
	int row = 0;
	if (str.length() % column == 0)
		row = str.length() / column;
	else
		row = row = str.length() / column + 1;
	vector<vector<char>> vec(row, vector<char>(column));

	for (int i = 0; i < row; ++i) {

		for (int j = 0; j < column; ++j) {
			if (num < str.length())
				vec[i][j] = str[num++];
			else
				vec[i][j] = ' ';
		}
	}

	int index = 0;
	int temp = column - 1;
	auto vec1 = vec;
	while (cipher != 0) {
		index = cipher % 10 - 1;

		if (mode == Encrypt)
			for (int i = 0; i < row; ++i)
				vec[i][temp] = vec1[i][index];
		else if (mode == Decrypt)
			for (int i = 0; i < row; ++i)
				vec[i][index] = vec1[i][temp];
		--temp;
		cipher /= 10;
	}
	
	num = 0;
	string str1(row * column, ' ');
	for (int i = 0; i < row; ++i)
		for (int j = 0; j < column; ++j)
			str1[num++] = vec[i][j];
	if (mode == Decrypt) {
		while (str1[--num] != ' ')
			break;
		str1.substr(0, num + 1);
	}

	return str1;
}

int main() {

	while (1) {
		system("cls");
		int temp,num, cipher;
		cout << "1.凯撒加密算法" << endl;
		cout << "2.凯撒解密算法" << endl;
		cout << "3.置换算法加密算法" << endl;
		cout << "4.置换算法解密算法" << endl;
		cout << "请选择要进行的操作:" ;
		cin >> temp;
		string str;
		cout << "请输入要操作的字符串:";
		getchar();
		getline(cin, str);
		switch (temp)
		{
		case 1:
			cout << "请输入密钥:";
			cin >> num;
			str = Caesar(str, num, Encrypt);
			cout << str<<endl; break;

		case 2:
			cout << "请输入密钥:";
			cin >> num;
			str = Caesar(str, num, Decrypt);
			cout << str<<endl; break;

		case 3:
			cout << "输入密钥(密钥为6位):";
			cin >> cipher;
			str = Permute(str, cipher, Encrypt);
			cout << "加密结果为:"; 
			cout << str << endl; break;
		
		case 4:
			cout << "输入密钥(密钥为6位):";
			cin >> cipher;
			str = Permute(str, cipher, Decrypt);
			cout << "解密结果为:";
			cout << str << endl; break;

		default:
			break;
		}

		system("pause");
	}

	return 0;
}

你可能感兴趣的:(杂货铺)