一、实验要求
使用熟悉的编程语言(Python、Java、C、C++等)设计并实现一个维吉尼亚密码体制的加密算法和解密算法。
1、加密:用户输入密钥,输入明文,程序正确输出密文。
2、解密:用户输入密钥,输入密文,程序正确输出明文。
二、算法设计
- 首先,先学习什么是维吉尼亚密码。
维吉尼亚密码是一种使用多个凯撒密码组成的密码字母表的加密算法,属于多表代换密码的一种简单形式。它是由意大利密码学家贝拉索于1553年首先发明的,但后来被误认为是法国外交官维吉尼亚所创造,因此得名。维吉尼亚密码的加密和解密需要一个表格,这个表格包含了26行字母表,每一行都由前一行向左偏移一位得到。另外,还需要一个密钥,这个密钥由字母组成,可以是任意长度。加密时,明文字母作为列,对应的密钥字母作为行,所确定的坐标上的字母即为对应的密文字母。解密时,则反过来根据密钥字母和密文字母找到明文字母。例如,假设明文为:ATTACKATDAWN,选择某一关键词并重复而得到密钥,如关键词为LEMON时,密钥为:LEMONLEMONLE。则加密和解密的过程如下:明文:ATTACKATDAWN 密钥:LEMONLEMONLE 密文:LXFOPVEFRNHR;解密: 密文:LXFOPVEFRNHR 密钥:LEMONLEMONLE 明文:ATTACKATDAWN。
- 其次,实现加密功能。
需要定义两个指针,分别指向明文和密钥的首部,然后进入一个循环次数为明文长度的循环,在每个循环内部,通过两个指针来确定密文的内容,然后写入密文中,最终进行输出密文。
- 最后,实现解密功能。
需要定义一个指针,指向密钥的首部,然后进入一个循环次数为密文长度的循环,在每个循环内部,拿着当前要处理的密文字符,从维吉尼亚方阵中的对应行(由密钥和密钥指针确定)进行一一比对,当找到相同的字符的时候,该字符在维吉尼亚方阵中所对应的列就是明文中的字符,然后依次写入明文,最终进行输出。
三、算法实现
维吉尼亚方阵 |
// 维吉尼亚方阵 char wjny_table[26][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'}, {'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', 'A'}, {'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B'}, {'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C'}, {'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D'}, {'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E'}, {'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F'}, {'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G'}, {'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'}, {'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'}, {'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}, {'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'}, {'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'}, {'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M'}, {'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'}, {'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'}, {'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'}, {'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q'}, {'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R'}, {'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S'}, {'U', 'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T'}, {'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U'}, {'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'}, {'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W'}, {'Y', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X'}, {'Z', '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'}, }; |
维吉尼亚加密代码 |
cout << "input the mingWen : "; cin >> mingWen; cout << "input the miYao : "; cin >> miYao;
int mingWen_index = 0, miYao_index = 0;
int mingWen_size = mingWen.size(), miYao_size = miYao.size(); for (int i = 0; i < mingWen_size; ++i) { int lie = mingWen[mingWen_index++] - 'A'; int hang = miYao[miYao_index++] - 'A'; miYao_index %= miYao_size; miWen.push_back(wjny_table[hang][lie]); }
cout << "miWen : "; for (auto ch : miWen) { cout << ch; } |
维吉尼亚解密代码 |
cout << "input the miWen : "; cin >> miWen; cout << "input the miYao : "; cin >> miYao;
int miYao_index = 0;
int miWen_size = miWen.size(), miYao_size = miYao.size(); for (int i = 0; i < miWen_size; ++i) { int hang = miYao[miYao_index++] - 'A'; miYao_index %= miYao_size; int lie = 0; for (auto ch : wjny_table[hang]) { if (ch == miWen[i]) { break; } else { lie++; } } mingWen.push_back('A' + lie); }
cout << "mingWen : "; for (auto ch : mingWen) { cout << ch; } |
四、实验结果
维吉尼亚加密运行结果 |
输入的明文为:HELLOBOYSANDGIRLS 输入的密钥为:GOODBYE 得到的密文为:NSZOPZSEGOQEEMXZG |
维吉尼亚解密运行结果 |
输入的密文为:NSZOPZSEGOQEEMXZG 输入的密钥为:GOODBYE 得到的明文为:HELLOBOYSANDGIRLS |