我们有一个非常旧的、不受支持的程序,它可以跨 SMB 共享复制文件。它有一个校验和算法来确定文件内容是否在复制之前发生了变化。该算法似乎很容易被愚弄——我们刚刚发现了一个示例,其中两个文件相同,除了单个“1”变为“2”外,返回相同的校验和。这是算法:
unsigned long GetFileCheckSum(CString PathFilename)
{
FILE* File;
unsigned long CheckSum = 0;
unsigned long Data = 0;
unsigned long Count = 0;
if ((File = fopen(PathFilename, "rb")) != NULL)
{
while (fread(&Data, 1, sizeof(unsigned long), File) != FALSE)
{
CheckSum ^= Data + ++Count;
Data = 0;
}
fclose(File);
}
return CheckSum;
}
我不是一个程序员(我是系统管理员),但我知道基于 XOR 的校验和会非常粗糙。对于两个大小相同但内容不同的文件,该算法返回相同校验和的可能性有多大?(我不期待一个确切的答案,“远程”或“很可能”很好。)
如果没有巨大的性能影响,如何改进它?
最后,是怎么回事fread()
?我快速浏览了文档,但无法弄清楚。是否Data
被依次设置到文件的每个字节?编辑:好的,所以它将文件读入unsigned long
(假设这里是 32 位操作系统)块。每个块包含什么?如果文件的内容是,那么第一遍abcd
的值是多少?Data
是(在 Perl 中):
(ord('a') << 24) & (ord('b') << 16) & (ord('c') << 8) & ord('d')