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

自学C语言实现XOR文件加解密时出现仅部分内容可解密问题求助

C语言XOR文件加解密代码问题排查及修复

核心问题列表

  • 文件打开模式错误:当前使用的"r"(只读文本)、"a"(追加文本)都是文本模式,处理包含非文本字符的加密文件时,会自动转换换行符、遇到0x00字节提前终止读取,必须改用二进制读写模式。
  • 读取函数选型错误:fgets是文本行读取函数,遇到换行、0x00、文件结束就会终止,无法完整读取二进制文件内容,应改用fread读取固定长度二进制块。
  • 字节计数逻辑错误:用strlen(temp_store)统计读取到的字节数,strlen遇到0x00就会提前返回,导致后半部分字节未被处理,直接使用fread的返回值作为实际读取字节数即可。
  • 输出模式错误:追加模式"a"会导致多次运行时内容拼接到已有文件尾部,应该用覆盖写模式。
  • 密钥偏移未全局维护:当前每个50字节块都从密钥起始位置开始计算偏移,会降低加密强度,建议全局维护密钥的偏移计数。
  • 缓冲区溢出风险:scanf("%s")未限制输入长度,超过数组长度会触发缓冲区溢出。

修复后可正常加解密的代码

#include <stdio.h>
#include <string.h>

int xor_file(void)
{
    FILE *src_file_ptr;
    FILE *dst_file_ptr;
    char infilename[96];
    char key[50];
    char outfilename[96];
    unsigned char temp_store[50]; // 用unsigned char避免符号位问题
    int plen;
    size_t read_len;
    int key_offset = 0; // 全局维护密钥偏移

    printf("Please enter the name of the input file: ");
    scanf("%95s", infilename); // 限制输入长度避免溢出
    printf("Please enter the name of the output file: ");
    scanf("%95s", outfilename);
    printf("Please enter the encryption/decryption key: ");
    scanf("%49s", key);
    plen = strlen(key);
    if (plen == 0) {
        printf("Key cannot be empty!\n");
        return 1;
    }

    // 二进制模式打开文件
    src_file_ptr = fopen(infilename, "rb");
    if (src_file_ptr == NULL) {
        printf("Input file does not exist!\n");
        return 1;
    }

    dst_file_ptr = fopen(outfilename, "wb"); // 二进制覆盖写模式
    if (dst_file_ptr == NULL) {
        printf("Cannot create output file!\n");
        fclose(src_file_ptr);
        return 1;
    }

    // 按块读取二进制内容
    while((read_len = fread(temp_store, 1, sizeof(temp_store), src_file_ptr)) > 0) {
        for (int i = 0; i < read_len; i++) {
            temp_store[i] = temp_store[i] ^ key[(key_offset + i) % plen];
            fputc(temp_store[i], dst_file_ptr);
        }
        key_offset = (key_offset + read_len) % plen; // 更新密钥偏移
    }

    fclose(dst_file_ptr);
    fclose(src_file_ptr);
    printf("Operation completed successfully!\n");
    return 0;
}

int main(void)
{
    return xor_file();
}

使用说明

该代码加密和解密逻辑完全一致:加密时输入原始文件路径、输出加密文件路径、密钥即可;解密时输入加密文件路径、输出解密文件路径、输入相同密钥即可得到原始文件。

内容的提问来源于stack exchange,提问作者jzakilla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:27:06