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