对重新下载的ftp进行自定义MD5/CRC检查,总是说文件与原始文件不同

本文关键字:文件 检查 CRC 原始 MD5 下载 新下载 自定义 ftp | 更新日期: 2023-09-27 18:19:47

我正在将文件加载到ftp,需要确保文件传输正确。为此,我稍后将重新下载该文件,并检查该文件是否与原始本地文件内容相同。为了做到这一点,我以小块的形式读取每个文件,并在内容上生成MD5和。

尽管MD5的代表性有限,但我认为就查看文件(通常大小高达2MB)是否存在差异而言,它已经足够了。现在,当我为每个流(一个是下载流,另一个是lokal文件读取流)生成MD5时,我遇到了两个流的MD5不同的问题(尽管前几个块在MD5方面是相同的)。文件本身是一个zip文件,可以在本地和ftp服务器上毫无问题地提取)。

我想知道的是:我的想法本身是否错误?或者我的代码有错误?或者为什么内容看起来不一样?

呼叫:

ftpMD5 = GeneriereMD5FuerStream(ftpAnsuchen.GetResponse().GetResponseStream());
lokalMD5 = GeneriereMD5FuerStream((new FileInfo(lokaleDateiPfad)).OpenRead());
if (ftpMD5.Equals(lokalMD5) == false)
{
    throw exception "Different";
}

方法代码:

    private string GeneriereMD5FuerStream(Stream leseStream)
    {
        string md5String = String.Empty;
        byte[] leseBuffer = new byte[2048];
        int bytesGelesen = 0;
        MD5 md5Converter = MD5.Create();
        bytesGelesen = leseStream.Read(leseBuffer, 0, leseBuffer.Length);
        md5String = BitConverter.ToString(md5Converter.ComputeHash(Encoding.Default.GetBytes(md5String + BitConverter.ToString(md5Converter.ComputeHash(leseBuffer)))));
        while (bytesGelesen > 0)
        {
            bytesGelesen = leseStream.Read(leseBuffer, 0, leseBuffer.Length);
            if (bytesGelesen > 0) 
            {
                md5String = BitConverter.ToString(md5Converter.ComputeHash(Encoding.Default.GetBytes(md5String + BitConverter.ToString(md5Converter.ComputeHash(leseBuffer)))));
            }
        }
        return md5String;
    }

对重新下载的ftp进行自定义MD5/CRC检查,总是说文件与原始文件不同

我强烈建议下载整个文件并对整个文件内容执行哈希。

正如keith所提到的,您不能保证您的缓冲区将包含一组值,因为网络延迟可能会成为一个问题。另一种方法是以设置的字节间隔计算md5散列,而不是基于缓冲区,但最后你会下载整个文件,所以从头开始就这样做。

MD5.ComputeHash还有一个应该使用的流重载。

https://msdn.microsoft.com/en-us/library/system.security.cryptography.md5(v=vs.110).aspx

计算MD5的方式对读入缓冲区的字节数很敏感。

看看这条线:

bytesGelesen = leseStream.Read(leseBuffer, 0, leseBuffer.Length);

对于文件,在读取最后一个块之前,bytesGelesen将始终为leseBuffer.Length

对于网络流,bytesGelesen可能不是leseBuffer的完整大小。

您有两个选项,将文件从网络流读取到磁盘,然后在此文件上使用当前的新方法来计算哈希(以确保每次读取迭代读取的字节的一致性)或更改哈希计算,使其返回相同的值,而不管每次读取调用读取的字节长度如何。

为了证明我的理论,当从FTP服务器提取文件时,只需写出bytesGelesen,并与从磁盘读取文件时进行比较。

在您的情况下有必要计算哈希吗?我想还有另一种方法可以检查文件是否已传输。您可以基于BackgroundWorker并在上传文件时监控进度。有人在这里描述过。