【问题标题】:Create my own check sum algorithm [closed]创建我自己的校验和算法[关闭]
【发布时间】:2012-01-13 12:23:16
【问题描述】:

我知道使用人们已经发明的校验和算法总是更好。我希望能够通过执行校验和来比较两个文件是否相同。这些文件通过网络位于两台不同的计算机中,并且由于它们跨网络,因此在处理像我这样的大文件时,执行校验和而不是复制整个文件会更快。 (我将首先执行其他测试,例如确保文件长度相同等。)

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

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 倍以上

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

或者也许我应该使用一个我不知道并且已经存在的更快的算法......

编辑

我的问题是:

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

【问题讨论】:

  • 查看 CRC32 实现,它们非常快。此外,您不应该使用 DOUBLE,因为您几乎肯定会遇到 DOUBLE 不准确的问题。
  • 经典的 CRC32 或 CRC64 怎么样?
  • 在比较具有相同长度的文件时使用此算法是否可靠...
  • 我很惊讶您不受 IO 限制。为什么 SHA256 托管?我认为非托管实现要快得多。 MD5 可能会更快(在密码学上不安全,但您似乎并不在意)
  • 如果两个 1GB 文件的前几个字节不同.. 计算整个文件的校验和会相当慢

标签: c# checksum file-read


【解决方案1】:

使用double 进行校验和容易出现浮点问题。我认为这是一个非常糟糕的主意。我也认为重新发明轮子也是一个糟糕的决定。有many checksum algorithms可供您重复使用。

还有一些相关的问题:

【讨论】:

    【解决方案2】:

    浮点数学是不确定的。在不同的计算机或 .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)))
    

    【讨论】:

      猜你喜欢
      • 2011-11-12
      • 2018-08-25
      • 2018-10-22
      • 2015-08-14
      • 2012-12-05
      • 2014-09-03
      • 2010-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多