首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >创建我自己的校验和算法

创建我自己的校验和算法
EN

Stack Overflow用户
提问于 2011-12-06 03:35:29
回答 2查看 1.3K关注 0票数 0

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

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

代码语言:javascript
运行
复制
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倍

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

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

编辑

我的问题是:

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-06 03:41:21

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

您的算法的另一个问题是,早期字节的贡献变得非常小。即仅文件的最后部分影响散列。一个简单的估计是,只有最后几个kB被考虑在内。这意味着你的散列不适合它的目的。

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

代码语言:javascript
运行
复制
(((buffer[i] + i)/2 + checkSum))*.45

buffer[i]*0.45/2 + i*0.45/2 + checkSum*0.45

通过求解递归,我们可以得到:

代码语言:javascript
运行
复制
Sum(buffer[i]/2*(0.45^(length-1)) + i*(0.45^(length-1)))

第二个术语只依赖于长度,所以当比较相同长度的文件时,剩下的就是:

代码语言:javascript
运行
复制
Sum(buffer[i]/2*(0.45^(length-1)))
票数 3
EN

Stack Overflow用户

发布于 2011-12-06 03:39:22

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

另外,还有一些相关问题:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8390782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档