创建我自己的校验和算法

本文关键字:算法 校验和 自己的 我自己 创建 | 更新日期: 2023-09-27 18:17:03

我知道使用人们已经发明的校验和算法总是更好。我想通过执行校验和来比较两个文件是否相同。文件在网络上的两台不同的计算机上,因为它们在网络上,所以在处理像我这样的大文件时,执行校验和比复制整个文件要快得多。(我将首先执行其他测试,例如确保文件长度相同等)

所以我创建了这个简单的算法:

private static double GetChecksum2(string file)
    {
        double checkSum = 0;
        var stream = File.OpenRead(file);
        // the bigger the chunck size the faster but the more memory usage by cpu
        // also when sending file over network it should not be that much more efficient
        int chunckSize = (int) Math.Pow(2,20); // 10 => kilobite   20 => megabite  30 => gigabite etc..
        byte[] buffer = new byte[chunckSize];
        int bytesRead = 0;
        while ( // while bytesRead > 0
            (bytesRead =
                (stream.Read(buffer, 0, buffer.Length)) // returns the number of bytes read or 0 if no bytes read
            ) > 0)
        {
            //buffer is now an array of size bytesRead
            // write those bytes to a file, perform checksum of file
            // etc...

            // temp check sum use a better algorithm I dont know if other computers will round 
            // doubles diferently
            for (int i = 0; i < bytesRead; i++)
            {
                checkSum = (((buffer[i] + i)/2 + checkSum))*.45;
            }

            //SHA256Managed sha = new SHA256Managed();
            //byte[] checksum = sha.ComputeHash(buffer);
        }
        return checkSum;
    }

我不知道两个不同文件的校验和使用这个算法实现的几率是多少。

对一个1.06 GB的文件执行校验和,耗时5.2秒,校验和结果为321840.207306214

当我使用SHA256Managed()算法时,它需要35.8秒。

7倍长

我知道使用这种算法具有相同校验和的两个文件的几率比使用我的算法要低得多。但使用我的算法要快得多,而且我认为这种可能性也应该很低……

或者我应该使用一个更快的算法,我不知道,它已经存在了…

编辑

我的问题是:

实现这个算法是否安全?我需要在我的网络上进行大量的文件传输,如果我可以使用校验和算法来比较文件,那就太好了。也许我可以将每个文件分成块,然后替换校验和不匹配的块!

创建我自己的校验和算法

浮点数学是不确定的。在不同的计算机或。net版本上,您可能会得到略有不同的结果。在你的算法中,这可以用epsilon比较来避免,但在许多算法中,这根本无法避免。

你的算法的另一个问题是早期字节的贡献变得指数级小。也就是说,只有文件的最后一部分影响散列。一个快速的估计是只考虑最后几个kB。这意味着你的哈希值不适合它的用途。

如果我们忽略舍入误差,我们可以简化公式:

(((buffer[i] + i)/2 + checkSum))*.45
buffer[i]*0.45/2 + i*0.45/2 + checkSum*0.45

求解递归得到:

Sum(buffer[i]/2*(0.45^(length-1)) + i*(0.45^(length-1)))

第二项只与长度有关,所以当比较长度相等的文件时,剩下的是:

Sum(buffer[i]/2*(0.45^(length-1)))

使用double作为校验和容易出现浮点问题。我觉得这不是个好主意。我还认为重新发明轮子也是一个糟糕的决定。有许多校验和算法可供您重用。

还有一些相关的问题:

  • 如何使用。net快速比较两个文件?
  • c#文件管理