在 C++ 中实现字母表
Implementing an alphabet in C++
我正在制作一个密码代码,可以读取二进制代码中的字母表。有没有办法实现自定义字母表(不使用 ASCII)?例如 alphabet={a,b,c,d,e,...,z,],[.,..., ,-} 每个字符都有一个数字 0,1,...,63 .所以,双射将从字母表的元素到 6 位数。
如何使用 C++ 中的简单函数实现此实现?我尝试使用 if 语句制作一个长度为 1 的字符串和相应的数字,然后将它们插入 .txt 文件,但没有成功。
string str1, ..., str63;
string sometext;
str1 = 'a';
// ...
cin >> sometext;
int k;
k = sometext.length();
string res;
ofstream out;
out.open("cipher.txt");
for (int i = 0; i < k; i++) {
res = sometext.substr(i, 1);
if (res == str1) {
res = '000000';
}
// ...
if (res == str63) {
res = '111111';
}
out << res;
}
我做了一个简单的 class 字母表来完成你的任务。它使用 std::unordered_map 来存储字符和二进制表示之间的映射,并使用此映射在这两种表示之间进行转换。它还计算二进制表示。 Class 可以指定任何字母表。
为了测试,我在 char 和 binary 之间进行了两次转换,并将结果输出到控制台。如果请求的值超出范围,则抛出 std::exception。
#include <string>
#include <unordered_map>
#include <cmath>
#include <stdexcept>
#include <iostream>
class Alphabet {
public:
Alphabet(std::string const & _chars)
: chars(_chars) {
size_t num_bits = std::ceil(std::log(std::max(size_t(1), chars.size()))
/ std::log(2) - 1e-6);
for (size_t i = 0; i < chars.size(); ++i) {
std::string bin;
for (ptrdiff_t j = num_bits - 1; j >= 0; --j)
bin += i & (1 << j) ? "1" : "0";
c2b[chars[i]] = bin;
b2c[bin] = chars[i];
}
}
std::string ToBin(char c) const {
auto it = c2b.find(c);
if (it == c2b.end())
throw std::runtime_error("Character '" +
std::string(1, c) + "' not in alphabet!");
return it->second;
}
char ToChar(std::string const & bin) const {
auto it = b2c.find(bin);
if (it == b2c.end())
throw std::runtime_error("Binary '" + bin + "' is out of range!");
return it->second;
}
std::string const & Chars() const {
return chars;
}
private:
std::string chars;
std::unordered_map<char, std::string> c2b;
std::unordered_map<std::string, char> b2c;
};
int main() {
try {
Alphabet alph("abcdef{}123");
std::cout << alph.ToBin('f') << std::endl;
std::cout << alph.ToChar("0011") << std::endl;
std::cout << alph.Chars() << std::endl;
return 0;
} catch (std::exception const & ex) {
std::cout << "Exception: " << ex.what() << std::endl;
return -1;
}
}
输出:
0101
d
abcdef{}123
我正在制作一个密码代码,可以读取二进制代码中的字母表。有没有办法实现自定义字母表(不使用 ASCII)?例如 alphabet={a,b,c,d,e,...,z,],[.,..., ,-} 每个字符都有一个数字 0,1,...,63 .所以,双射将从字母表的元素到 6 位数。
如何使用 C++ 中的简单函数实现此实现?我尝试使用 if 语句制作一个长度为 1 的字符串和相应的数字,然后将它们插入 .txt 文件,但没有成功。
string str1, ..., str63;
string sometext;
str1 = 'a';
// ...
cin >> sometext;
int k;
k = sometext.length();
string res;
ofstream out;
out.open("cipher.txt");
for (int i = 0; i < k; i++) {
res = sometext.substr(i, 1);
if (res == str1) {
res = '000000';
}
// ...
if (res == str63) {
res = '111111';
}
out << res;
}
我做了一个简单的 class 字母表来完成你的任务。它使用 std::unordered_map 来存储字符和二进制表示之间的映射,并使用此映射在这两种表示之间进行转换。它还计算二进制表示。 Class 可以指定任何字母表。
为了测试,我在 char 和 binary 之间进行了两次转换,并将结果输出到控制台。如果请求的值超出范围,则抛出 std::exception。
#include <string>
#include <unordered_map>
#include <cmath>
#include <stdexcept>
#include <iostream>
class Alphabet {
public:
Alphabet(std::string const & _chars)
: chars(_chars) {
size_t num_bits = std::ceil(std::log(std::max(size_t(1), chars.size()))
/ std::log(2) - 1e-6);
for (size_t i = 0; i < chars.size(); ++i) {
std::string bin;
for (ptrdiff_t j = num_bits - 1; j >= 0; --j)
bin += i & (1 << j) ? "1" : "0";
c2b[chars[i]] = bin;
b2c[bin] = chars[i];
}
}
std::string ToBin(char c) const {
auto it = c2b.find(c);
if (it == c2b.end())
throw std::runtime_error("Character '" +
std::string(1, c) + "' not in alphabet!");
return it->second;
}
char ToChar(std::string const & bin) const {
auto it = b2c.find(bin);
if (it == b2c.end())
throw std::runtime_error("Binary '" + bin + "' is out of range!");
return it->second;
}
std::string const & Chars() const {
return chars;
}
private:
std::string chars;
std::unordered_map<char, std::string> c2b;
std::unordered_map<std::string, char> b2c;
};
int main() {
try {
Alphabet alph("abcdef{}123");
std::cout << alph.ToBin('f') << std::endl;
std::cout << alph.ToChar("0011") << std::endl;
std::cout << alph.Chars() << std::endl;
return 0;
} catch (std::exception const & ex) {
std::cout << "Exception: " << ex.what() << std::endl;
return -1;
}
}
输出:
0101
d
abcdef{}123