V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiaoyanbot
V2EX  ›  .NET

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

  •  
  •   xiaoyanbot · 2020-06-25 11:30:31 +08:00 · 2228 次点击
    这是一个创建于 1620 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用

    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);

    11 条回复    2020-06-25 12:56:07 +08:00
    xiaoyanbot
        1
    xiaoyanbot  
    OP
       2020-06-25 11:40:48 +08:00
    是因为 private const int BUFFER_SIZE = 1200000 导致的?
    xiaoyanbot
        2
    xiaoyanbot  
    OP
       2020-06-25 11:57:13 +08:00
    使用 BufferedStream 之后, 跟 BUFFER_SIZE 也没关系。 换了文件也是出来这个:

    D41D8CD98F00B204E9800998ECF8427E
    Athrob
        3
    Athrob  
       2020-06-25 12:22:08 +08:00
    https://dotnetfiddle.net/PkbHWP
    .Net Core 测试正常
    xiaoyanbot
        4
    xiaoyanbot  
    OP
       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
        5
    xiaoyanbot  
    OP
       2020-06-25 12:30:30 +08:00
    独特的那个,无论换什么文件,都是出来固定的一个字符: D41D8CD98F00B204E9800998ECF8427E

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

    计算正确:
    1b3851736679ffb7eb8b06bb751bc3bf

    独特的:
    d41d8cd98f00b204e9800998ecf8427e

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

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

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

    一样了:

    ~~~


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




    ~~~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2699 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 07:40 · PVG 15:40 · LAX 23:40 · JFK 02:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.