System.Security.Cryptography 中计算文件 md5 值, File.OpenRead 加了 BufferedStream 之后,计算出来值,不一致, 请教是怎么回事?

2020-06-25 11:30:31 +08:00
 xiaoyanbot

使用

using System.Security.Cryptography;

var md5 = MD5.Create()

方式一:


var openFile = File.OpenRead(filePath)

var hash = md5.ComputeHash(openFile);


方式二:

var stream = new BufferedStream((File.OpenRead(openFileDialog1.FileName)), BUFFER_SIZE);

md5.ComputeHash(stream);

2124 次点击
所在节点    .NET
11 条回复
xiaoyanbot
2020-06-25 11:40:48 +08:00
是因为 private const int BUFFER_SIZE = 1200000 导致的?
xiaoyanbot
2020-06-25 11:57:13 +08:00
使用 BufferedStream 之后, 跟 BUFFER_SIZE 也没关系。 换了文件也是出来这个:

D41D8CD98F00B204E9800998ECF8427E
Athrob
2020-06-25 12:22:08 +08:00
https://dotnetfiddle.net/PkbHWP
.Net Core 测试正常
xiaoyanbot
2020-06-25 12:29:27 +08:00
@Athrob


整理了一下, 好像是写法的问题:



~~~


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{

String path = "C:\\Users\\ABC\\Downloads\\DiskGenius.exe";

var md5 = MD5.Create();
var openFile = File.OpenRead(path);


var hash = md5.ComputeHash(openFile);
Console.WriteLine("计算正确:");
Console.WriteLine(BitConverter.ToString(hash).Replace("-", String.Empty).ToLower());


Console.WriteLine();



Console.WriteLine("独特的:");
var stream = new BufferedStream(openFile);
var hash2 = md5.ComputeHash(stream);
Console.WriteLine(BitConverter.ToString(hash2).Replace("-", String.Empty).ToLower());


Console.WriteLine();


Console.WriteLine("另外一种用法(计算正确):");
FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
var bufferedStream3 = new BufferedStream(fileStream, 1024 * 4);
var hash3 = md5.ComputeHash(bufferedStream3);
Console.WriteLine(BitConverter.ToString(hash3).Replace("-", String.Empty).ToLower());


Console.ReadLine();
}
}
}



~~~
xiaoyanbot
2020-06-25 12:30:30 +08:00
独特的那个,无论换什么文件,都是出来固定的一个字符: D41D8CD98F00B204E9800998ECF8427E

.NET 4.6 (没用 core )
xiaoyanbot
2020-06-25 12:33:01 +08:00
stream 情况下, 又获取了一遍 stream 导致的?
geelaw
2020-06-25 12:34:43 +08:00
难道不是因为第二个调用的时候 openFile 已经到文件结尾了吗?你可以 Seek 回开头再做第二次调用,就会一样了。
geelaw
2020-06-25 12:37:15 +08:00
另外搜索一下 D41D8CD98F00B204E9800998ECF8427E 就知道这是长度为 0 的字节串的 MD5
xiaoyanbot
2020-06-25 12:37:25 +08:00
~~~

计算正确:
1b3851736679ffb7eb8b06bb751bc3bf

独特的:
d41d8cd98f00b204e9800998ecf8427e

另外一种用法(计算正确):
1b3851736679ffb7eb8b06bb751bc3bf

~~~
xiaoyanbot
2020-06-25 12:38:06 +08:00
@geelaw 感谢
xiaoyanbot
2020-06-25 12:56:07 +08:00
@geelaw
@Athrob

感谢,感谢。 是因为二次调用,流翻转的原因

一样了:

~~~


// 二次调用,翻转到开头
fileStream.Seek(0, SeekOrigin.Begin);




~~~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/684653

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX