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

如何每次从文件读取16字节存入数组并逐块加密写入输出文件

逐16字节文件加密的正确实现

原代码的核心问题

  1. 错误处理不到位:文件打开失败后没有终止函数,后续对空指针操作会直接崩溃。
  2. 未处理末尾不足16字节的块:原循环只读取完整的16字节块,剩余字节会被直接丢弃。
  3. 悬空指针风险:如果shift_encrypt返回的是函数内局部数组的指针,fwrite会写入无效内存(局部变量在函数返回后会被销毁)。
  4. 资源泄漏:没有关闭输入文件流input_stream,会导致系统资源占用。

修正后的完整实现

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

#define MAX_PATH_LEN 256
#define CIPHER_BLOCK_SIZE 16

// 调整shift_encrypt为传入输出缓冲区,避免返回局部指针
void shift_encrypt(const char *plaintext, const char *password, char *ciphertext) {
    // 这里替换为你的实际加密逻辑,示例为简单异或加密
    for (int i = 0; i < CIPHER_BLOCK_SIZE; i++) {
        ciphertext[i] = plaintext[i] ^ password[i % strlen(password)];
    }
}

void encryption(char filename[MAX_PATH_LEN], char password[CIPHER_BLOCK_SIZE + 1]) {
    char output[256];
    snprintf(output, sizeof(output), "%s.ecb", filename);
    
    FILE *output_stream = fopen(output, "wb");
    if (output_stream == NULL) {
        perror(output);
        return; // 打开失败直接终止函数
    }

    FILE *input_stream = fopen(filename, "rb");
    if (input_stream == NULL) {
        perror(filename);
        fclose(output_stream); // 先关闭已打开的输出流,避免泄漏
        return;
    } 

    char plaintext[CIPHER_BLOCK_SIZE];
    char ciphertext[CIPHER_BLOCK_SIZE];
    size_t bytes_read;

    // 循环读取,每次最多读16字节,返回实际读取的字节数
    while ((bytes_read = fread(plaintext, 1, CIPHER_BLOCK_SIZE, input_stream)) > 0) {
        // 处理不足16字节的块:按PKCS#7标准填充(可根据加密算法调整)
        if (bytes_read < CIPHER_BLOCK_SIZE) {
            int pad_len = CIPHER_BLOCK_SIZE - bytes_read;
            memset(plaintext + bytes_read, pad_len, pad_len);
        }

        // 加密到预先分配的ciphertext缓冲区
        shift_encrypt(plaintext, password, ciphertext);
        // 写入完整的16字节加密块
        fwrite(ciphertext, 1, CIPHER_BLOCK_SIZE, output_stream);
    }

    // 关闭所有文件流,释放资源
    fclose(input_stream);
    fclose(output_stream);
}

关键细节说明

  • 读取逻辑调整:用fread(plaintext, 1, CIPHER_BLOCK_SIZE, ...)代替原写法,这样能准确获取实际读取的字节数,不会漏掉末尾的不完整块。
  • 填充机制:块加密算法通常要求输入块大小固定,示例中用PKCS#7填充(填充值等于需要填充的字节数),解密时需要对应移除填充。
  • 加密函数安全:让shift_encrypt使用外部传入的缓冲区存储加密结果,彻底避免局部指针悬空问题。
  • 资源管理:无论成功失败,都确保打开的文件流被关闭,防止资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:10:28