在将fread()转换为整数时,如果文件大小不是4个字节的倍数会发生什么?

时间:2014-01-20 03:25:02

标签: c encryption cryptography fread

我正在实现块大小为16位的Feistel密码。我从输入文件读取整数(32位),加密并写入输出文件。

unsigned int buf1, buf2;
FILE *fin = fopen("input", "r");
FILE *fout = fopen("output", "w");
while(!feof(fin)) {
    fread(&buf1, 4, 1, fin);
    buf2  = encrypt(buf1);
    fwrite(&buf2, 4, 1, fout);
}

该计划差不多完成了。唯一的问题是加密后跟解密不是源文件。它们几乎相同但不同之处仅在于最后一位。 我的问题是如果文件中的字节数不是4的倍数会发生什么。最后一次调用fread()会发生什么?

2 个答案:

答案 0 :(得分:3)

如果文件中的字节数不是4的倍数,则对fread()的最后一次调用将返回0.

  

size_t fread(void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream);
  “fread函数返回成功读取的元素数,如果遇到读取错误或文件结束,则可能小于nmemb。”

fread()的结果值应用于检测不完整的读取 EOF。 OP代码会经常读取一次。

还建议使用uint32_t代替unsigned int以获得更高的可移植性并检查`fwrite()结果。

uint32_t buf1, buf2;
int cnt;
while((cnt = fread(&buf1, sizeof buf1, 1, fin)) == 1) {
  buf2  = encrypt(buf1);
  if (fwrite(&buf2, sizeof buf2, 1, fout) != 1) {
    Handle_WriteError();
  }
}

答案 1 :(得分:0)

您需要提前知道您正在阅读的文件的大小(使用stat()或等效文件),读取可用的完整块数,然后处理剩余字节(如果有的话),作为一种特殊情况,也许是通过填充。如果您不想要密文扩展,那么请查看块窃取操作模式,这些模式可用于ECB和CBC模式。