原生C实现XOR Cipher文件加解密程序无法解密问题求助
问题分析与修复方案
你的程序无法完成解密(甚至加密逻辑本身也存在错误),核心问题及修复方案如下:
1. 未读取原文件内容到缓冲区
你直接对malloc分配的未初始化缓冲区buff执行异或操作,再写回文件——这相当于用随机垃圾数据覆盖了原文件,根本没完成加密,更谈不上解密。必须先把文件内容读取到缓冲区,再进行异或处理。
2. fwrite参数顺序错误
fwrite的标准调用格式为:fwrite(数据指针, 单个元素大小, 元素个数, 文件指针)。你当前写法是fwrite(buff, size, sizeof(char), fp),虽然sizeof(char)为1时结果可能巧合正确,但逻辑完全错误,应改为fwrite(buff, sizeof(char), size, fp)。
3. (次要)异或密钥的位处理
你用(char)KEY截取了32位密钥的低8位,这本身没问题(8位密钥也可用于异或加密),但要记住:异或加密的特性是加密两次等于解密,只要保证加密和解密用同一个固定密钥,逻辑正确的话,运行两次程序就能完成解密。
修复后的完整代码
#include<stdio.h> #include<stdlib.h> #include<windows.h> #include<stdint.h> #include<stddef.h> void flush_n(){ int c = 0; while((c = getchar())!= '\n' && c!= EOF); } int main(void){ char path[281]; puts("Please enter the path of the file you want to encrypt\\decrypt:"); scanf("%280s",path); FILE*fp = fopen(path,"rb+"); if(fp==NULL){ fprintf(stderr,"Unable to open the file!\n"); Sleep(2000); return EXIT_FAILURE; } // 获取文件大小 fseek(fp,0,SEEK_END); size_t size = ftell(fp); rewind(fp); // 分配缓冲区并读取文件内容 char*buff = (char*)malloc(size*sizeof(char)); if(buff==NULL){ fprintf(stderr,"Unable to allocate memory!\n"); Sleep(2000); return EXIT_FAILURE; } // 关键步骤:读取原文件内容到缓冲区 size_t read_count = fread(buff, sizeof(char), size, fp); if(read_count != size){ fprintf(stderr,"Failed to read file completely!\n"); free(buff); fclose(fp); Sleep(2000); return EXIT_FAILURE; } const uint32_t KEY = 0x4FC5D4B; // 对读取到的文件内容执行异或处理 for(size_t i = 0;i < size; i++) buff[i] ^= (char)KEY; // 回到文件开头,写入处理后的内容 rewind(fp); // 修正fwrite参数顺序 fwrite(buff, sizeof(char), size, fp); fclose(fp); free(buff); flush_n(); MessageBoxA(NULL,"The file has been successfully encrypted\\decrypted!","DONE!",MB_OK|MB_ICONINFORMATION); puts("Please press any key to close this window..."); getchar(); return EXIT_SUCCESS; }
修复说明
- 新增
fread步骤,将原文件内容读取到缓冲区,这是加密/解密的核心基础 - 修正
fwrite参数顺序,符合C标准库调用规范 - 增加读取完整性检查,避免部分读取导致的文件损坏
- 写入前再次调用
rewind(fp)确保回到文件开头,提升程序稳定性
现在程序可正常工作:第一次运行加密文件,第二次运行即可完成解密。
内容的提问来源于stack exchange,提问作者Zerocool_m12
相关产品推荐
相关产品推荐

