维吉尼亚加密和解密算法
1. 算法概述
维吉尼亚加密是一种基于多表代换的加密方法,它使用一个密钥对明文进行加密。每个字母的加密和解密都依赖于密钥中的相应字母。
核心:根据字母表将字符串翻译成数字, 然后将其按照密钥个数进行分组,分别与秘钥集合相加,得到密文。
2. 加密过程
- 输入:明文字符串和密钥字符串。
- 初始化:创建一个空的加密字符串。
- 遍历明文:
- 对于每个字符,检查是否为字母。
- 如果是字母,计算密钥字符的偏移量(将密钥字符转换为小写字母,然后减去 ‘a’)。
- 根据偏移量对明文字符进行加密:
- 如果是小写字母,使用公式
(明文字符 - 'a' + 偏移量) % 26 + 'a'
进行加密。
- 如果是大写字母,使用公式
(明文字符 - 'A' + 偏移量) % 26 + 'A'
进行加密。
- 如果不是字母,直接将字符添加到加密字符串中。
- 输出:返回加密字符串。
3. 解密过程
- 输入:密文字符串和密钥字符串。
- 初始化:创建一个空的解密字符串。
- 遍历密文:
- 对于每个字符,检查是否为字母。
- 如果是字母,计算密钥字符的偏移量(将密钥字符转换为小写字母,然后减去 ‘a’)。
- 根据偏移量对密文字符进行解密:
- 如果是小写字母,使用公式
(密文字符 - 'a' - 偏移量 + 26) % 26 + 'a'
进行解密。
- 如果是大写字母,使用公式
(密文字符 - 'A' - 偏移量 + 26) % 26 + 'A'
进行解密。
- 如果不是字母,直接将字符添加到解密字符串中。
- 输出:返回解密字符串。
4. 代码实现
以下是上述设计思路的代码实现:
VigenereCipher.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #pragma once #include <string>
namespace sword{ namespace util{ class VigenereCipher { public: VigenereCipher(const std::string& key);
std::string encrypt(const std::string& plaintext); std::string decrypt(const std::string& ciphertext);
private: std::string key; }; } using util::VigenereCipher; }
|
VigenereCipher.cpp
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include "VigenereCipher.h"
namespace sword { namespace util { VigenereCipher::VigenereCipher(const std::string& key) : key(key) {}
std::string VigenereCipher::encrypt(const std::string& plaintext) { std::string encryptedText; int keyLength = key.length(); for (size_t i = 0; i < plaintext.length(); ++i) { char charToEncrypt = plaintext[i]; if (isalpha(charToEncrypt)) { int shift = tolower(key[i % keyLength]) - 'a'; if (islower(charToEncrypt)) { encryptedText += (charToEncrypt - 'a' + shift) % 26 + 'a'; } else { encryptedText += (charToEncrypt - 'A' + shift) % 26 + 'A'; } } else { encryptedText += charToEncrypt; } } return encryptedText; }
std::string VigenereCipher::decrypt(const std::string& ciphertext) { std::string decryptedText; int keyLength = key.length(); for (size_t i = 0; i < ciphertext.length(); ++i) { char charToDecrypt = ciphertext[i]; if (isalpha(charToDecrypt)) { int shift = tolower(key[i % keyLength]) - 'a'; if (islower(charToDecrypt)) { decryptedText += (charToDecrypt - 'a' - shift + 26) % 26 + 'a'; } else { decryptedText += (charToDecrypt - 'A' - shift + 26) % 26 + 'A'; } } else { decryptedText += charToDecrypt; } } return decryptedText; } } }
|
实验步骤
- 定义密钥:使用密钥
"key"
。
- 创建
VigenereCipher
对象:使用上述密钥初始化 VigenereCipher
对象。
- 定义明文:使用明文
"Hello, World!"
。
- 加密明文:调用
encrypt
方法对明文进行加密。
- 解密密文:调用
decrypt
方法对加密后的密文进行解密。
- 输出结果:打印明文、加密后的密文和解密后的明文。
实验结果
1 2 3
| 明文: Hello, World! 加密后: Rijvs, Uyvjn! 解密后: Hello, World!
|
结果分析
加密结果:
- 明文
"Hello, World!"
使用密钥 "key"
加密后得到密文 "Rijvs, Uyvjn!"
。
- 可以看到,字母字符被正确加密,而非字母字符(如逗号和空格)保持不变。
解密结果:
- 密文
"Rijvs, Uyvjn!"
使用相同的密钥 "key"
解密后恢复为原始明文 "Hello, World!"
。
- 这表明加密和解密过程是对称的,能够正确还原原始明文。