C++ XOR加密-解密问题
C++ XOR encryption - decryption issue
我遵循了 stephan-brumme 网站上的 XOR 加密教程(不幸的是我无法包括 URL 因为我没有足够的声誉)。我想做的是:读取 example.txt 文件的内容并解密其中包含的文本。例如,这是example.txt的内容:
\xe7\xfb\xe0\xe0\xe7
这个,当使用密码"password"解密时应该return "hello"。这是我得到的代码:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
std::string decode(const std::string& input)
{
const size_t passwordLength = 9;
static const char password[passwordLength] = "password";
std::string result = input;
for (size_t i = 0; i < input.length(); i++)
result[i] ^= ~password[i % passwordLength];
return result;
}
int main(int argc, char* argv[])
{
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << decode(line);
}
myfile.close();
}
return 0;
}
这是 运行 应用程序的结果:
click for image
如您所见,解密不成功。现在,如果我这样做,它不会读取 .txt,而是直接解密文本,如下所示:
cout << decode("\xe7\xfb\xe0\xe0\xe7");
完美运行:
click for image
我做错了什么?
非常感谢! :)
我敢打赌 example.txt 包含字符“\”、'x'、'e'、“7”等。您必须阅读这些字符,处理所有反斜杠转义,并且 然后喂它解码。
\xe7 是用十六进制值 E7 表示 单个 字符的常用方法。 (这很可能是单个字符 'ç',具体取决于您的字符集)。如果你想存储(加密的)可读文本,我建议删除 \x,并让文件包含像 "e7fbe0e0e7" 这样的行。然后
- 将每一行读入一个字符串。
- 将每对字符从十六进制数转换为整数,并将结果存储在一个字符中。
- 将该字符存储在字符串中。
- 然后异或解密字符串。
或者,确保文件包含您需要的实际二进制字符。
另请注意,您正在与密码的终止空字节进行异或运算。你是故意的吗?
相同字符的字符异或为零,因此结果可能包含零。 std::string
不喜欢这样,因为零终止了字符串。
对于实际的 encoding/decoding,您也可以使用 std::vector<char>
而不是 std::string
。您必须更改 decode
函数来处理 vector<char>
和read/write二进制文件。
编辑:仅使用 std::string
,并且 std::string decode(const std::string& input)
int main()
{
std::string line = "hello";
{
line = decode(line);
std::ofstream myfile("example.txt", std::ios::binary);
myfile.write(line.data(), line.size());
//Edit 2 *************
//std::cout << std::hex;
//for (char c : line)
// std::cout << "\x" << (0xff & c);
//*************
//This will make sure width is always 2
//For example, it will print "\x01\x02" instead of "\x1\x2"
std::cout << std::hex << std::setfill('0');
for (char c : line)
std::cout << "\x" << std::setw(2) << (0xff & c);
std::cout << std::endl;
}
{
std::ifstream myfile("example.txt", std::ios::binary | std::ios::ate);
int filesize = (int)myfile.tellg();
line.resize(filesize);
myfile.seekg(0);
myfile.read(&line[0], filesize);
line = decode(line);
std::cout << line << std::endl;
}
return 0;
}
我遵循了 stephan-brumme 网站上的 XOR 加密教程(不幸的是我无法包括 URL 因为我没有足够的声誉)。我想做的是:读取 example.txt 文件的内容并解密其中包含的文本。例如,这是example.txt的内容:
\xe7\xfb\xe0\xe0\xe7
这个,当使用密码"password"解密时应该return "hello"。这是我得到的代码:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
std::string decode(const std::string& input)
{
const size_t passwordLength = 9;
static const char password[passwordLength] = "password";
std::string result = input;
for (size_t i = 0; i < input.length(); i++)
result[i] ^= ~password[i % passwordLength];
return result;
}
int main(int argc, char* argv[])
{
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << decode(line);
}
myfile.close();
}
return 0;
}
这是 运行 应用程序的结果: click for image
如您所见,解密不成功。现在,如果我这样做,它不会读取 .txt,而是直接解密文本,如下所示:
cout << decode("\xe7\xfb\xe0\xe0\xe7");
完美运行: click for image
我做错了什么?
非常感谢! :)
我敢打赌 example.txt 包含字符“\”、'x'、'e'、“7”等。您必须阅读这些字符,处理所有反斜杠转义,并且 然后喂它解码。
\xe7 是用十六进制值 E7 表示 单个 字符的常用方法。 (这很可能是单个字符 'ç',具体取决于您的字符集)。如果你想存储(加密的)可读文本,我建议删除 \x,并让文件包含像 "e7fbe0e0e7" 这样的行。然后 - 将每一行读入一个字符串。 - 将每对字符从十六进制数转换为整数,并将结果存储在一个字符中。 - 将该字符存储在字符串中。 - 然后异或解密字符串。
或者,确保文件包含您需要的实际二进制字符。
另请注意,您正在与密码的终止空字节进行异或运算。你是故意的吗?
相同字符的字符异或为零,因此结果可能包含零。 std::string
不喜欢这样,因为零终止了字符串。
对于实际的 encoding/decoding,您也可以使用 std::vector<char>
而不是 std::string
。您必须更改 decode
函数来处理 vector<char>
和read/write二进制文件。
编辑:仅使用 std::string
,并且 std::string decode(const std::string& input)
int main()
{
std::string line = "hello";
{
line = decode(line);
std::ofstream myfile("example.txt", std::ios::binary);
myfile.write(line.data(), line.size());
//Edit 2 *************
//std::cout << std::hex;
//for (char c : line)
// std::cout << "\x" << (0xff & c);
//*************
//This will make sure width is always 2
//For example, it will print "\x01\x02" instead of "\x1\x2"
std::cout << std::hex << std::setfill('0');
for (char c : line)
std::cout << "\x" << std::setw(2) << (0xff & c);
std::cout << std::endl;
}
{
std::ifstream myfile("example.txt", std::ios::binary | std::ios::ate);
int filesize = (int)myfile.tellg();
line.resize(filesize);
myfile.seekg(0);
myfile.read(&line[0], filesize);
line = decode(line);
std::cout << line << std::endl;
}
return 0;
}