C#网络上的高速MD5 / SHA哈希

时间:2011-01-19 22:24:45

标签: c# performance networking md5 sha

在我目前正在进行的C#项目中,我们试图通过网络计算大量文件的MD5(当前底池为270万,客户端底池可能超过1000万)。根据我们正在处理的文件数量,速度是个问题。

我们这样做的原因是验证文件是否已复制到其他位置而不进行修改。

我们目前使用以下代码计算文件的MD5

MD5 md5 = new MD5CryptoServiceProvider();
StringBuilder sb = new StringBuilder();

byte[] hashMD5 = null;

try
{
   // Open stream to file to get MD5 hash for, create hash
   using (FileStream fsMD5 = new FileStream(sFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
      hashMD5 = md5.ComputeHash(fsMD5);
}
catch (Exception ex)
{
   clsLogging.logError(clsLogging.ErrorLevel.ERROR, ex);
}

string md5sum = "";
if (hashMD5 != null)
{
   // Change hash into readable text
   foreach (byte hex in hashMD5)
      sb.Append(hex.ToString("x2"));
    md5sum = sb.ToString();
}

然而,速度并不是我的经理一直希望的。我们对计算MD5的文件的方式和数量进行了一些更改(即我们不对我们不复制的文件执行此操作...直到今天我的经理改变了主意所有文件必须为它们计算MD5,以防将来某个客户希望使用我们的程序进行操作,以便所有文件都被复制我猜)

我意识到网络速度可能是一个主要因素(100Mbit / s)。有没有一种有效的方法来计算网络上文件内容的MD5?

提前致谢。 特雷弗沃森

编辑:将所有代码放在块中,而不仅仅是其中的一部分。

3 个答案:

答案 0 :(得分:3)

瓶颈是整个文件必须通过网络流式传输/复制,你看起来好看...... 不同的散列函数(md5 / sha256 / sha512)具有几乎相同的计算时间

此问题的两种可能解决方案:

1)在远程系统上运行一个哈希并将哈希存储到单独的文件中 - 如果在您的环境中可以实现。

2)创建文件的分部哈希,以便您只复制文件的一部分。 我的意思是这样的:

part1Hash = md5(file.getXXXBytesFromFileAtPosition1)
part2Hash = md5(file.getXXXBytesFromFileAtPosition2)
part3Hash = md5(file.getXXXBytesFromFileAtPosition3)
finalHash = part1Hash ^ part2Hash ^ part3Hash;

你必须测试文件的哪一部分是最佳的,因此哈希值保持唯一。

希望有所帮助...

编辑:改为按位xor

答案 1 :(得分:3)

一种可能的方法是使用.Net 4.0中的并行任务库。 100Mbps仍然是瓶颈,但你应该看到适度的改进。

我去年写了一个小应用程序,它遍历文件夹树检查文件夹和文件安全设置的顶层。在10Mbps WAN上运行需要大约7分钟才能完成我们的一个大文件共享。当我并行操作时,执行时间降低到1分多钟。

答案 2 :(得分:1)

为什么不尝试在每个侦听端口的地方安装“客户端”,当发出信号时,会计算所请求文件的MD5哈希值。

主服务器只需要询问每个客户端计算MD5。使用这种分布式方法,您将获得所有客户端的组合速度并减少网络拥塞。