一、加密解密原理
可以根据一个示例来解释原理
明文:TOBEHAPPY
秘钥:HELLO
进行加密解密的过程:
步骤1.给26个A-Z字母按顺序1-26编号
字母 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
序号 | 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 |
步骤2.找到明文对应的字母序号
字母 | T | O | B | E | H | A | P | P | Y |
序号 | 20 | 15 | 2 | 5 | 8 | 1 | 16 | 16 | 25 |
步骤3找到秘钥对应的字母序号
字母 | H | E | L | L | O |
序号 | 8 | 5 | 12 | 12 | 15 |
步骤4 将明文序号和秘钥序号相加,得到密文序号以及密文。
得到的结果有两种情况:
设a属于明文序号,b书属于秘钥序号,c属于密文序号
若a+b<=25则c=a+b
若a+b>25 则c=a+b-26
比如T的序号20和H的序号8相加等于28>25,则对应密文为28-26=2
注:明文有9个字母,秘钥有5个字母,当明文前5个字母的序列和秘钥的序列相加后,第6个字母的序号和秘钥的第1个字母序号相加,重复使用秘钥的序号
因此得到密文序号
明文序号 | 20 | 15 | 2 | 5 | 8 | 1 | 16 | 16 | 25 |
秘钥序号 | 8 | 5 | 12 | 12 | 15 | 8 | 5 | 12 | 12 |
相加 | 2 | 20 | 14 | 17 | 23 | 9 | 21 | 2 | 11 |
根据密文序号得到密文:
序号 | 2 | 20 | 14 | 17 | 23 | 9 | 21 | 2 | 11 |
字母 | B | T | N | Q | W | I | U | B | K |
二、加密解密代码:
#include<iostream>
using namespace std;
class Vigenere{
public:
char *plaintext;
char *key;
int NumPlaintext[100];//明文的下标
int NumKey[100];//秘钥的下标
Vigenere(char *key){ //无论解密或加密都需要秘钥,故可以在构造函数中用init生成秘钥编号
initKey(key);
}
void Encrypt(char *plaintext)
{
transPlainToCipher(plaintext);
}
void Decrypt(char *plaintext)
{
transPlainToCipher(plaintext);
}
private:
//static int LengthOfKey;//j为秘钥的长度
int j;
int NumCiphertext[100];
char Ciphertext[100];
void initKey(char *key){ //初始化秘钥,得到秘钥字母对应的编号
j=0;
while(*key) //得到秘钥的下标
{
NumKey[j]=(int)(*key)-int('A')+1;
*key++;
j++;
}
}
void transPlainToCipher(char *plaintext ) //密文生成秘钥
{
int i=0;//i为明文的长度,j为秘钥的长度
cout<<j<<endl;
while(*plaintext)//得到明文的下标
{
NumPlaintext[i]=(int)(*plaintext)-int('A')+1;
*plaintext++;
i++;
}
//生成密文下标
int t=i;//循环明文的长度,t=0时停止while循环
int k=0;//为密文的下标数组的下标
int m=0;
while(t--)
{
if(m==j)//若循环的下标超过密文的长度,密文就重新循环
{
m=0;
}
cout<<k<<":"<<NumPlaintext[k]<<endl;
cout<<m<<":"<<NumKey[m]<<endl;
int add = NumPlaintext[k]+NumKey[m];
//cout<<"add:"<<add<<endl;
NumCiphertext[k]= add%26;
//cout<<"秘钥"<<NumCiphertext[k]<<endl;
k++;
m++;
}
//十进制ASCII转字符
for (int j=0;j<i;j++)
{
Ciphertext[j]=(char)NumCiphertext[j]+'A'-1;
cout<<Ciphertext[j]<<" ";
}
cout<<endl;
}
};
int main()
{
char *plain=NULL;
char *secretekey=NULL;
char plaintext[100];
char key[100];
while(1){
cout<<"*****************************************"<<endl;
cout<<"Please choose encrypt or decrypt"<<endl;
cout<<"if you wanna encrypt please input 1"<<endl;
cout<<"if you wanna decrypt pleaseinput 2"<<endl;
cout<<"if you wanna quit please input 3"<<endl;
cout<<"****************************************"<<endl;
int options;
cin>>options;
if(options==1)
{
cout<<"please input the plaintext"<<endl;
cin>>plaintext;
cout<<"Please input the key"<<endl;
cin>>key;
char *plain=plaintext;
char *secretekey=key;
Vigenere Encrypt(secretekey);
Encrypt. Encrypt(plain);
}else if(options==2)
{
cout<<"please input the plaintext"<<endl;
cin>>plaintext;
cout<<"Please input the key"<<endl;
cin>>key;
char *plain=plaintext;
char *secretekey=key;
Vigenere Encrypt(secretekey);
Encrypt. Encrypt(plain);
}else if(options==3){
break;
}
else{
cout<<"input error,please try again"<<endl;
continue;
}
}
}
代码参考https://github.com/gao27024037/Encryption/blob/master/Encryption/Vigenere.h