我有三个字段:string Title
,byte[] Body
和byte[] Data
,我想从中计算单个哈希作为检查,以确保它们没有被篡改或损坏。
在Python中,我可以连续几次使用md5.update()
来执行此操作。但我在C#中找不到类似的功能。要使用MD5.ComputeHash(),我需要将所有源代码复制到单个字节[]中,这是我想避免的一个步骤。
如何将它们一起散列到一个哈希中,而不必将数据复制到临时缓冲区?
答案 0 :(得分:14)
几乎所有哈希算法的设计方式都可以连续地为多个块中的数据提供数据。结果就像整个数据一次被散列一样。
创建例如MD5CryptoServiceProvider并为每个块调用TransformBlock Method,为最后一个块调用TransformFinalBlock Method:
MD5 md5 = new MD5CryptoServiceProvider();
// For each block:
md5.TransformBlock(block, 0, block.Length, block, 0);
// For last block:
md5.TransformFinalBlock(block, 0, block.Length);
// Get the hash code
byte[] hash = md5.Hash;
答案 1 :(得分:1)
.Net Standard和.Net Core中还有使用IncrementalHash
的解决方案IncrementalHash md5 = IncrementalHash.Create(HashAlgorithmName.MD5)
// For each block:
md5.AppendData(block);
// Get the hash code
byte[] hash = md5.GetHashAndReset();
答案 2 :(得分:0)
使用纯.NET,我认为没有办法更新和MD5哈希。但是,Windows在crypt.dll中定义了MD5Update函数。您可以使用Interop来充分利用这一点。
否则,.NET c#中有一个PHP等价物的实现,位于SO:Problem porting PHP crypt() function to C#
PS:我肯定会选择合并的临时变量解决方案: - )
答案 3 :(得分:0)
你可以在哈希值上创建一个哈希值。
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] totalHash= md5.ComputeHash(md5.ComputeHash(part1).Concat(md5t.computeHash(part2)));
不会创建字节数组的副本,但会散列哈希值的串联。
答案 4 :(得分:0)
在三个不同的值上调用ComputeHash函数将创建三个不同的字节数组结果。然后必须以某种方式组合这些结果以产生单个散列。没有办法解决这个问题。它将在堆中创建三个新对象。它会计算三次哈希(一个相当慢的操作)而不是一次。
我认为执行所需操作的最高效方法是继续将源值复制到单个字节数组中并获取其中的哈希值。
您没有说明为什么要避免这种做法。我认为它在简单性和可维护性方面获胜。这是一种自我记录,明显的方法。这是最高效的方法。我真的没有看到一个缺点。
答案 5 :(得分:-1)
您必须将它们全部组合在一个变量中,然后计算MD5哈希值。我没有看到任何捷径。
你知道,这里提出的大多数解决方案只是尝试在同一行上运行多个命令(“一个衬里”)或实现“引擎盖下”的东西,然后组合你的字段然后哈希......