Zip包内SVG文件哈希值不一致问题排查求助
Zip归档中SVG文件哈希值计算不一致的问题
我有一个包含SVG文件的Zip归档文件,需要获取SVG文件内容的哈希值并存储,以便后续执行时检查文件是否被修改。但目前遇到的问题是,即使文件未被修改,两次计算得到的哈希值却不相同。
存储哈希值的原代码
using (ZipArchive archive = ZipFile.OpenRead(zipPath)) { using (HashAlgorithm sha1 = SHA1.Create()) { foreach (var entry in archive.Entries) { byte[] hash; using (GZipStream svgStream = new GZipStream(entry.Open(), CompressionMode.Decompress)) { hash = sha1.ComputeHash(svgStream); } documents.Add(new BsonDocument("_id", entry.Name).Add("Hash", hash)); } } } collection.InsertMany(documents);
验证哈希值的原代码
using (ZipArchive archive = ZipFile.OpenRead(zipFile)){ foreach(var entry in archive.Entries) { using (GZipStream svgStream = new GZipStream(entry.Open(), CompressionMode.Decompress)) { var hash = sha1.ComputeHash(svgStream); if (hashes.ContainsKey(entry.Name) && hashes[entry.Name].SequenceEqual(hash)) { // 哈希相同时的逻辑,从未执行到这里 } // 哈希不同时的逻辑 } } }
我不确定通过var hash = sha1.ComputeHash(svgStream);这种方式获取流的哈希值是否正确?
问题原因
你犯了一个关键错误:ZipArchiveEntry.Open()返回的流已经是解压缩后的原始文件内容,不需要再用GZipStream二次解压缩。强行套GZipStream会把正常的SVG二进制数据当成GZip压缩格式处理,导致读取的内容完全错误,自然每次计算的哈希值都不一样。
修正后的代码
存储哈希值的代码
using (ZipArchive archive = ZipFile.OpenRead(zipPath)) { using (HashAlgorithm sha1 = SHA1.Create()) { foreach (var entry in archive.Entries) { // 直接使用entry.Open()返回的流,无需GZipStream using (Stream svgStream = entry.Open()) { byte[] hash = sha1.ComputeHash(svgStream); documents.Add(new BsonDocument("_id", entry.Name).Add("Hash", hash)); } } } } collection.InsertMany(documents);
验证哈希值的代码
using (ZipArchive archive = ZipFile.OpenRead(zipFile)) { foreach(var entry in archive.Entries) { using (Stream svgStream = entry.Open()) { var hash = sha1.ComputeHash(svgStream); if (hashes.ContainsKey(entry.Name) && hashes[entry.Name].SequenceEqual(hash)) { // 哈希相同时的逻辑,现在可以正常执行 } // 哈希不同时的逻辑 } } }
额外注意事项
- 确保两次计算哈希时使用的是同一版本的哈希算法实例,或者每次都重新创建(就像存储代码里那样),避免因算法实例状态问题导致哈希错误。
- 如果SVG文件存在文本编码差异(比如换行符格式不同),也可能导致哈希不一致,但你的问题明显是流处理错误导致的,修正后应该可以解决。
内容的提问来源于stack exchange,提问作者Vali Moldovan
相关产品推荐
相关产品推荐

