我有以下用例:
- 从文件中读取 n 个字节
- 计算这 n 个字节的 (MD5) 哈希
- 从文件中读取接下来的 m 个字节
- 为文件计算 (MD5) 哈希,最多 n+m 个字节
增量散列文件不是问题,只需调用TransformBlock
andTransformFinalBlock
。
问题是我需要多个共享其开始字节的数据散列,但是在我调用TransformFinalBlock
读取Hash
第一个n
字节后,我无法继续使用同一个对象进行散列并且需要一个新的对象。
搜索问题时,我发现Python和OpenSSL都可以选择复制散列对象来实现此目的:
hash.copy()
返回散列对象的副本(“克隆”)。这可以用来有效地计算共享一个公共初始子串的字符串的摘要。
EVP_MD_CTX_copy_ex() 可用于将消息摘要状态从输入复制到输出。如果要散列仅在最后几个字节中不同的大量数据,这很有用。out 必须在调用此函数之前进行初始化。
尽我所能搜索,我找不到任何可以让我在调用其方法之前有效== 复制这样一个对象的股票 C# HashAlgorithm的东西——然后继续用克隆对其余数据进行哈希处理。Clone()
TransformFinalBlock
我发现了一个MD5 的 C# 参考实现,它可以很容易地适应支持克隆(*),但强烈希望使用现有的东西而不是将这样的东西引入代码库。
(*) 事实上,据我所知,我费心检查的任何散列算法(与加密/解密相反)都是可以复制的,因为这种算法的所有状态都是摘要的一种形式。
那么我在这里遗漏了什么还是标准 C#/.NET 接口实际上没有提供复制哈希对象的方法?
另一个数据点:
微软自己的加密服务本机 API有一个函数CryptDuplicateHash
,其状态的文档引用:
CryptDuplicateHash 函数可用于创建以相同内容开头的两个不同内容的单独哈希。
自 Windows XP 以来一直存在。:-|
请注意。MD5:用例对密码不敏感。只是可靠的文件校验和。