注意事项
凯撒密码通过旋转字母表来加密文本,保持数字和符号不变。它曾在古代用于加密机密信息,但在今天的视角看来,它只是一个玩具密码。
本文的目的不是推广凯撒密码,而是演示如何在英语的实现中使用 C++ 的特性。
目标
- 提供一种加密
char[]
、std::string
和文件的方法。
- 这是通过一个使用迭代器工作的函数模板来实现的。
语言
C++11,C++ 语言标准的 2011 版本。
您的 C++ 编译器必须支持 lambda 函数、基于范围的
for()
循环和初始化列表,才能成功编译本文中的源代码片段以及附带的完整程序。
参数与设计思路
程序的核心函数名为
caesar_cipher()
,它有四个参数:
姓名 |
描述 |
src_begin |
源的起始迭代器 |
src_end |
源的结束迭代器 |
dest_begin |
目标的起始迭代器 |
移位 |
一个表示字母表位移的整数 |
传递迭代器而不是实际容器的方法有两个优点:
- 函数与容器无关。
- 函数的实现得到简化。
使用示例
- 好的
1 2 3 4
|
std::string s("Hello, World!");
caesar_cipher(s.begin(), s.end(), s.begin(), 4); // s == "Lipps, Asvph!"
caesar_cipher(s.begin(), s.end(), s.begin(), -4); // s == "Hello, World!"
|
- 坏的
1 2 3 4 5
|
const std::vector<char> vc{'D', 'b', 'f', 't', 'b', 's'};
std::list<char> lc(vc.size());
caesar_cipher(vc.begin(), vc.end(), lc.begin(), -1);
// lc == std::list<char>({'C', 'a', 'e', 's', 'a', 'r'})
|
- 丑陋的
1 2 3 4 5
|
const char ca[]{"Sqjzanxwn!"};
std::unique_ptr<char[]> upca(new char[sizeof ca]);
caesar_cipher(std::begin(ca), std::end(ca), upca.get(), 4);
// std::strcmp(upca.get(), "Wunderbar!") == 0
|
核心函数源代码
如果您需要处理文件的完整程序,请跳到下一节。
备注
- 当字母表位移时,它会循环。这意味着对于长度为 26 的字母表,位移 27 与位移 1 相同,位移 52 与不位移相同。
- 第 11 行的目的是将
shift
截断为可以在 std::rotate()
中使用的值。
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
|
#include <algorithm>
#include <cctype>
#include <string>
template <typename InputIterator, typename OutputIterator>
OutputIterator caesar_cipher(InputIterator src_begin, InputIterator src_end, OutputIterator dest_begin, int shift)
{
const std::string ab("abcdefghijklmnopqrstuvwxyz"); // AlphaBet
std::string rot_ab(ab); // ROTated AlphaBet
shift %= static_cast<int> (ab.length());
if (shift < 0)
std::rotate(rot_ab.rbegin(), rot_ab.rbegin() - shift, rot_ab.rend());
else
std::rotate(rot_ab.begin(), rot_ab.begin() + shift, rot_ab.end());
return std::transform(src_begin, src_end, dest_begin, [ab, rot_ab](unsigned char c) -> char {
if (std::isalpha(c))
{
if (std::isupper(c))
return std::toupper(rot_ab.at(ab.find(std::tolower(c))));
return rot_ab.at(ab.find(c));
}
return c;
});
}
|
完整程序源代码
请下载文章末尾的 ZIP 存档附件。
有用链接
感谢
附件:[caesar.zip]