C++异或加密
XOR encryption with c++
我已经实现了一种相当简单的方法来将字符串加密和解密到文件中,然后再返回。
我使用的方法如下所示:
string encrypt(string msg, string key) {
string tmp(key);
while (key.size() < msg.size()) key += tmp;
for (std::string::size_type i = 0; i < msg.size(); ++i) msg[i] ^= key[i];
return msg;
}
string decrypt(string msg, string key) {
return encrypt(msg, key);
}
然而,我使用的一些键不是很有用。该字符串被正确加密并写入文件。但是当我尝试解密所有内容时(将文件加载到字符串中,解密,写回另一个文件)新文件明显更小并且不包含存储在其中的全部信息。
到目前为止我试过的键是:
string crypt = "abc"; //works kinda well
string crypt = "_H84M!-juJHFXGT01X1*G6a$gEv"; //doesnt work
string crypt = "H84MjuJHFXGT01X1G6agEv"; //doesnt work either
我希望你能帮助我并给我任何关于如何选择可用密钥的建议。
文件处理代码:
ofstream temp;
temp.open("temp", ios::in | ios::trunc);
temp << encrypt(buffer, crypt);
temp.close();
ifstream in(file);
string content((std::istreambuf_iterator<char>(in)) (std::istreambuf_iterator<char>()));
ofstream plain;
plain.open(newfile, ios::in | ios::trunc);
plain << decrypt(content, crypt);
plain.close();
因为你的加密字符串中有二进制数据,你应该使用未格式化的 write
方法而不是 operator<<
:
ofstream os(...);
std::string encrypted = ...;
os.write( encrypted.data(), encrypted.size() );
请注意,如果您需要在一个文件中使用多个加密字符串,您可能希望在实际数据之前写入数据大小。然后你用 istream::read()
:
读取数据大小和数据
void write( std::ostream &out, const std::string &encrypted )
{
size_t length = encrypted.size();
of.write( &length, sizeof( length ) );
of.write( encryped.data(), length );
}
std::string read( std::istream &in )
{
size_t length = 0;
in.read( &length, sizeof( length ) );
std::string str( length );
in.read( &str[0], length );
return str;
}
注意 2:将加密数据存储在 std::vector<char>
中而不是 std::string
中可能是个好主意,这将防止许多问题 - 您将无法使用隐式假定的许多函数该字符串以 null 结尾。
我刚刚写了一个完整的、最小的、有效的例子。
#include <fstream>
#include <iostream>
#include <string>
static std::string str_xor(const std::string &data, const std::string &key) {
std::string result(data.size(), '[=10=]');
for (std::size_t i = 0, i < data.size(); i++) {
result[i] = data[i] ^ key[i % key.size()];
}
return result;
}
int main(int argc, char **argv) {
if (argc != 3) {
std::cerr << "usage: xor <datafile> <keyfile>\n";
return 1;
}
std::ifstream data_in(argv[1]);
std::string data(
(std::istreambuf_iterator<char>(data_in)),
(std::istreambuf_iterator<char>()));
data_in.close();
std::ifstream key_in(argv[2]);
std::string key(
(std::istreambuf_iterator<char>(key_in)),
(std::istreambuf_iterator<char>()));
key_in.close();
std::string result = str_xor(data, key);
std::ofstream data_out(argv[1]);
data_out << result;
data_out.close();
return 0;
}
它仍然缺少对文件的错误检查,以防找不到它们。但是如果你将两个现有文件的名称传递给它,它就像一个魅力,使用第二个文件作为密钥加密第一个文件。
中给出的充分理由,请勿在实践中使用此程序
好的,您的所有回答和评论都为我指明了正确的方向,但并没有直接在我的程序中起作用。
首先,我按照Slava建议的方式修改了加密算法。其次,我切换了文件处理新方法获取加密文件的整个长度,并通过 char 数组强制每个字符转换为新字符串。我知道这不太好,但我可以将整个代码保留为字符串类型。
所以我想到了以下内容:
ifstream in(file, ios::binary);
in.seekg(0, ios::end); // go to the end
int length = in.tellg(); // report location (this is the length)
in.seekg(0, ios::beg); // go back to the beginning
char* content = new char[length]; // allocate memory for a buffer of appropriate dimension
in.read(content, length); // read the whole file into the buffer
string content2 = "";
for (int i = 0; i < length; i++) con31 += con3[i]; //append to string character by character
ofstream plain;
plain.open(newfile, ios::in | ios::trunc);
plain << decrypt(content2, crypt);
plain.close();
这对我来说效果很好。我希望我没有犯一些严重的错误。
我已经实现了一种相当简单的方法来将字符串加密和解密到文件中,然后再返回。 我使用的方法如下所示:
string encrypt(string msg, string key) {
string tmp(key);
while (key.size() < msg.size()) key += tmp;
for (std::string::size_type i = 0; i < msg.size(); ++i) msg[i] ^= key[i];
return msg;
}
string decrypt(string msg, string key) {
return encrypt(msg, key);
}
然而,我使用的一些键不是很有用。该字符串被正确加密并写入文件。但是当我尝试解密所有内容时(将文件加载到字符串中,解密,写回另一个文件)新文件明显更小并且不包含存储在其中的全部信息。
到目前为止我试过的键是:
string crypt = "abc"; //works kinda well
string crypt = "_H84M!-juJHFXGT01X1*G6a$gEv"; //doesnt work
string crypt = "H84MjuJHFXGT01X1G6agEv"; //doesnt work either
我希望你能帮助我并给我任何关于如何选择可用密钥的建议。
文件处理代码:
ofstream temp;
temp.open("temp", ios::in | ios::trunc);
temp << encrypt(buffer, crypt);
temp.close();
ifstream in(file);
string content((std::istreambuf_iterator<char>(in)) (std::istreambuf_iterator<char>()));
ofstream plain;
plain.open(newfile, ios::in | ios::trunc);
plain << decrypt(content, crypt);
plain.close();
因为你的加密字符串中有二进制数据,你应该使用未格式化的 write
方法而不是 operator<<
:
ofstream os(...);
std::string encrypted = ...;
os.write( encrypted.data(), encrypted.size() );
请注意,如果您需要在一个文件中使用多个加密字符串,您可能希望在实际数据之前写入数据大小。然后你用 istream::read()
:
void write( std::ostream &out, const std::string &encrypted )
{
size_t length = encrypted.size();
of.write( &length, sizeof( length ) );
of.write( encryped.data(), length );
}
std::string read( std::istream &in )
{
size_t length = 0;
in.read( &length, sizeof( length ) );
std::string str( length );
in.read( &str[0], length );
return str;
}
注意 2:将加密数据存储在 std::vector<char>
中而不是 std::string
中可能是个好主意,这将防止许多问题 - 您将无法使用隐式假定的许多函数该字符串以 null 结尾。
我刚刚写了一个完整的、最小的、有效的例子。
#include <fstream>
#include <iostream>
#include <string>
static std::string str_xor(const std::string &data, const std::string &key) {
std::string result(data.size(), '[=10=]');
for (std::size_t i = 0, i < data.size(); i++) {
result[i] = data[i] ^ key[i % key.size()];
}
return result;
}
int main(int argc, char **argv) {
if (argc != 3) {
std::cerr << "usage: xor <datafile> <keyfile>\n";
return 1;
}
std::ifstream data_in(argv[1]);
std::string data(
(std::istreambuf_iterator<char>(data_in)),
(std::istreambuf_iterator<char>()));
data_in.close();
std::ifstream key_in(argv[2]);
std::string key(
(std::istreambuf_iterator<char>(key_in)),
(std::istreambuf_iterator<char>()));
key_in.close();
std::string result = str_xor(data, key);
std::ofstream data_out(argv[1]);
data_out << result;
data_out.close();
return 0;
}
它仍然缺少对文件的错误检查,以防找不到它们。但是如果你将两个现有文件的名称传递给它,它就像一个魅力,使用第二个文件作为密钥加密第一个文件。
中给出的充分理由,请勿在实践中使用此程序好的,您的所有回答和评论都为我指明了正确的方向,但并没有直接在我的程序中起作用。
首先,我按照Slava建议的方式修改了加密算法。其次,我切换了文件处理新方法获取加密文件的整个长度,并通过 char 数组强制每个字符转换为新字符串。我知道这不太好,但我可以将整个代码保留为字符串类型。
所以我想到了以下内容:
ifstream in(file, ios::binary);
in.seekg(0, ios::end); // go to the end
int length = in.tellg(); // report location (this is the length)
in.seekg(0, ios::beg); // go back to the beginning
char* content = new char[length]; // allocate memory for a buffer of appropriate dimension
in.read(content, length); // read the whole file into the buffer
string content2 = "";
for (int i = 0; i < length; i++) con31 += con3[i]; //append to string character by character
ofstream plain;
plain.open(newfile, ios::in | ios::trunc);
plain << decrypt(content2, crypt);
plain.close();
这对我来说效果很好。我希望我没有犯一些严重的错误。