我正在实现块大小为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()会发生什么?
答案 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模式。