mar*_*ton 4 c++ algorithm checksum
我们有一个非常古老的,不受支持的程序,它可以跨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;
}
Run Code Online (Sandbox Code Playgroud)
我不是一个程序员(我是一个系统管理员),但我知道基于XOR的校验和将非常粗糙.对于具有不同内容的两个相同大小的文件,此算法返回相同校验和的可能性是多少?(我不期待一个确切的答案,"远程"或"非常可能"是好的.)
如果没有巨大的性能影响,它怎么能改进?
最后,这是怎么回事fread()?我快速扫描了文档,但我无法弄清楚.是Data依次设置文件的每个字节?编辑:好的,所以它正在读取文件unsigned long(让我们假设这里有32位操作系统)块.每个块包含什么?如果文件的内容是abcd,Data第一遍的值是多少?是(在Perl中):
(ord('a') << 24) & (ord('b') << 16) & (ord('c') << 8) & ord('d')
Run Code Online (Sandbox Code Playgroud)
您可以使用如下公式轻松改进算法:
Checksum = (Checksum * a + Data * b) + c;
Run Code Online (Sandbox Code Playgroud)
如果 a、b 和 c 是大素数,这应该会返回良好的结果。之后,旋转(而不是移位!)校验和位将进一步改进它。
使用素数,这是与线性同余生成器使用的算法类似的算法- 它保证长周期和良好的分布。
| 归档时间: |
|
| 查看次数: |
4012 次 |
| 最近记录: |