- 置换密码
置换密码算法的原理是不改变明文字符,只将字符在明文中的排列顺序改变,从而实现明文信息的加密。置换密码也叫换位密码。它的加密方法是将明文中的字母按照给定的顺序安排在一个矩阵中,然后用根据密钥提供的顺序重新组合矩阵中的字母,形成密文。例如,明文为 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 4 5 3 2 6
1 2 3 4 5 6
根据上面的置换,将原有矩阵中的字母按照第 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
- 具体代码
#include<bits/stdc++.h>
using namespace std;
void encrypt(){
string key, plain;
cout << "请输入明文(不需要输入间隔):\n";
cin >> plain;
cout << "请输入密钥:\n";
cin >> key;
int l;
l = plain.size() / key.size();
char a='a';
for (int i = plain.size(); i % key.size() != 0; i++)
{
plain.push_back(a++);//通过判断在明文数组后面补齐
}
cout << endl;
cout<<"明文矩阵"<<endl;
for (int i = 0; i < plain.size(); i++)//输出列宽为密钥长度的矩阵
{
cout << plain[i]<<" ";
if (i % key.size() == key.size()-1)
{
cout << "\n";
}
}
cout<<endl;
cout<<"密钥排序数组:"<<endl;
vector<int>v(key.size(),0);//密钥排序数组
int count=0;
for(int i=0;i<key.size();i++){
for(int j=0;j<key.size();j++){
if(key[i]>key[j]){
count++;
}
}
v[i]=count;
count=0;
}
for(int i=0;i<v.size();i++){
cout<<v[i]+1<<" ";
}
cout<<endl;
cout << "\n排序后:"<<endl;
string temp=plain;
for (int i = 0; i < key.size(); i++){
for (int k = 0; k <= l; k++){
plain[i+k*key.size()]=temp[v[i]+k*key.size()];
}
}
for (int i = 0; i < plain.size(); i++)//输出列宽为密钥长度的矩阵
{
cout << plain[i]<<" ";
if (i % key.size() == key.size()-1)
{
cout << "\n";
}
}
cout<<endl;
cout<<"密文:"<<plain<<endl;
}
void decrypt(){
string key, plain;
cout << "请输入密文:\n";
cin >> plain;
cout << "请输入密钥:\n";
cin >> key;
int l;
l = plain.size() / key.size();
cout<<endl;
cout<<"密文矩阵"<<endl;
for (int i = 0; i < plain.size(); i++)//输出列宽为密钥长度的矩阵
{
cout << plain[i]<<" ";
if (i % key.size() == key.size()-1)
{
cout << "\n";
}
}
cout<<endl;
cout<<"密钥排序数组:"<<endl;
vector<int>v(key.size(),0);//密钥排序数组
int count=0;
for(int i=0;i<key.size();i++){
for(int j=0;j<key.size();j++){
if(key[i]>key[j]){
count++;
}
}
v[i]=count;
count=0;
}
for(int i=0;i<v.size();i++){
cout<<v[i]+1<<" ";
}
cout<<endl;
cout << "\n还原后:"<<endl;
string temp=plain;
for (int i = 0; i < key.size(); i++){
for (int k = 0; k <= l; k++){
plain[v[i]+k*key.size()]=temp[i+k*key.size()];
}
}
for (int i = 0; i < plain.size(); i++)//输出列宽为密钥长度的矩阵
{
cout << plain[i]<<" ";
if (i % key.size() == key.size()-1)
{
cout << "\n";
}
}
cout<<endl;
cout<<"明文:"<<plain<<endl;
}
int main()
{
int n=0;
cout<<"置换密码"<<endl;
cout<<"1.加密"<<endl;
cout<<"2.解密"<<endl;
cout<<"3.退出"<<endl;
while(n!=3){
cin>>n;
switch (n)
{
case 1:
encrypt();//加密
cout<<"请继续选择功能"<<endl;
break;
case 2:
decrypt();//解密
cout<<"请继续选择功能"<<endl;
break;
case 3:
n=3;
break;
default:
cout<<"输入错误,请重新输入!"<<endl;
break;
}
}
system("pause");
return 0;
}
- 运行结果