You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:45:33