C++文件加解密项目中PNG解密后损坏问题求助
问题描述
我是BS第一学期的学生,正在做一个磁盘文件加解密项目。我将文件逐字符读取并存储到string对象中,先进行XOR加密,再进行Base64加密。现在解密后保存的PNG文件无法打开,提示损坏,但以文本形式查看输入和输出图像的数据是一致的。附上我的代码,希望得到帮助。
#include<iostream> #include<string> #include<fstream> #include<Base64.h> using namespace macaron; using namespace std; string xor_(string ch){ int i =0, count = ch.size(); string str=""; char c,n; while (i<count){ c = ch[i]; n = c^'p'; str = str+n; i++; } return str; } int main(){ ifstream f("save.png", ios::binary | ios::in); char c,n,p; string cs1=""; int count=1; // Reading file character by character and storing it in cs1 string datatype variable while(f.get(c)){ count++; cs1 = cs1+c; } // Encrypting cs1 with xor method string encrypted = xor_(cs1); // Encrypted string further encrypted using base64 string encoded_string = Base64::Encode(encrypted); //Replacing the encrypted file std::ofstream out("save.txt"); out << encoded_string; out.close(); string decoded; Base64::Decode(encoded_string,decoded); string decrypted = xor_(decoded); std::ofstream out1("save2.png"); out1 << decrypted; out1.close(); //cout<<decrypted<<endl; cout<<(cs1==decrypted); return 0; }
解决方案
问题出在写入PNG文件时没有以二进制模式打开输出流。
- 用
std::ofstream out1("save2.png");默认是文本模式,这种模式会自动处理特殊字符(比如把ASCII值0x1A的字符识别为文件结束符),还会在Windows系统上转换换行符(将\n转为\r\n),导致写入磁盘的字节和原文件不一致,虽然字符串比较显示cs1==decrypted为真,但实际文件已损坏。
修改方法:打开输出流时添加ios::binary标志:
std::ofstream out1("save2.png", ios::binary | ios::out);
额外优化建议:
- 读取文件时,先获取文件大小给
string预分配内存,避免循环拼接字符串的性能损耗:f.seekg(0, ios::end); int fileSize = f.tellg(); f.seekg(0, ios::beg); cs1.reserve(fileSize); while(f.get(c)){ cs1 += c; } - 无需手动调用
close(),ofstream的析构函数会自动关闭文件流。
修改后,解密保存的PNG文件即可正常打开。
内容的提问来源于stack exchange,提问作者farhan jatt
相关产品推荐
相关产品推荐

