前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.NET 6.0 中你的MD5用对了吗?

.NET 6.0 中你的MD5用对了吗?

作者头像
郑子铭
发布2023-11-03 10:45:00
4850
发布2023-11-03 10:45:00
举报
文章被收录于专栏:DotNet NB && CloudNative

前言

本文的项目环境为 .NET 6.0 (.NET 5.0 以上都支持)

正文

在 .NET中获取字符串的 MD5 相信是非常容易的事情吧, 但是随便在网上搜一搜发现流传的版本还不少呢,比如:

1、StringBuilder 版本(应该算是官方版本了,使用的人最多,我发现在 ABP 中也是使用的这个

2、BitConverter 版本

3、StringConcat 版本 (字符串拼接,用的人很少,估计都知道性能不好)

但是它们是否是最佳实现? 我们来测试一下

StringBuilder 版本

代码语言:javascript
复制
public static string Md5_StringBuilder(string input)
{
    using var md5 = MD5.Create();
    var inputBytes = Encoding.UTF8.GetBytes(input);
    var hashBytes = md5.ComputeHash(inputBytes);
    var sb = new StringBuilder();
    foreach (var hashByte in hashBytes)
    {
        sb.Append(hashByte.ToString("X2"));
    }
    return sb.ToString();
}

BitConverter 版本

代码语言:javascript
复制
public static string Md5_BitConverter(string input)
{
    using var md5 = MD5.Create();
    var inputBytes = Encoding.UTF8.GetBytes(input);
    var hashBytes = md5.ComputeHash(inputBytes);
    return BitConverter.ToString(hashBytes).Replace("-", "");
}

StringConcat 版本

代码语言:javascript
复制
public static string Md5_StringConcat(string input)
{
    using var md5 = MD5.Create();
    var inputBytes = Encoding.UTF8.GetBytes(input);
    var hashBytes = md5.ComputeHash(inputBytes);
    var output = string.Empty;
    foreach (var hashByte in hashBytes)
    {
        output += hashByte.ToString("X2");
    }
    return output;
}

性能对比

先上我测试得到的数据(本机配置: 4 核 8 线程, 测试结果可能不一致)

看结果,的确是字符串拼接性能最差,但是 StringBuilder 好像也不是很高效啊,那个什么 Static 是啥玩意,怎么性能这么好,相对于 StringBuilder, 单线程性能提高了 3 倍, 多线性提高了 5 倍???

没错,这就是我要说的, 从 .net 5.0 开始提供了 2 个非常高效的方法

  • Convert.ToHexString
  • MD5.HashData

Convert.ToHexString 实例版本

代码语言:javascript
复制
public static string MD5_HexConvert_Instance(string input)
{
    using var md5 = MD5.Create();
    var inputBytes = Encoding.UTF8.GetBytes(input);
    var hashBytes = md5.ComputeHash(inputBytes);
    return Convert.ToHexString(hashBytes);
}

MD5.HashData 静态版本(强烈建议)

代码语言:javascript
复制
public static string MD5_HexConvert_Static(string input)
{
    var inputBytes = Encoding.UTF8.GetBytes(input);
    var hashBytes = MD5.HashData(inputBytes);
    return Convert.ToHexString(hashBytes);
}

总结

强烈建议 使用 MD5.HashData + Convert.ToHexString, 代码性能最高,也最简洁,只有 3 行

一定不要 忘记释放 MD5,我看网上很多在使用实例版本 MD5.Create() 后都没有 Dispose, 这会导致 内存泄漏!

最后放上我的完整的测试代码

代码语言:javascript
复制
using System.Text;
using System.Security.Cryptography;
using System.Diagnostics;

namespace ConsoleTest;

class Program
{
    public static string Md5_StringBuilder(string input)
    {
        using var md5 = MD5.Create();
        var inputBytes = Encoding.UTF8.GetBytes(input);
        var hashBytes = md5.ComputeHash(inputBytes);
        var sb = new StringBuilder();
        foreach (var hashByte in hashBytes)
        {
            sb.Append(hashByte.ToString("X2"));
        }
        return sb.ToString();
    }

    public static string Md5_StringConcat(string input)
    {
        using var md5 = MD5.Create();
        var inputBytes = Encoding.UTF8.GetBytes(input);
        var hashBytes = md5.ComputeHash(inputBytes);
        var output = string.Empty;
        foreach (var hashByte in hashBytes)
        {
            output += hashByte.ToString("X2");
        }
        return output;
    }

    public static string Md5_BitConverter(string input)
    {
        using var md5 = MD5.Create();
        var inputBytes = Encoding.UTF8.GetBytes(input);
        var hashBytes = md5.ComputeHash(inputBytes);
        return BitConverter.ToString(hashBytes).Replace("-", "");
    }

    public static string MD5_HexConvert_Instance(string input)
    {
        using var md5 = MD5.Create();
        var inputBytes = Encoding.UTF8.GetBytes(input);
        var hashBytes = md5.ComputeHash(inputBytes);
        return Convert.ToHexString(hashBytes);
    }

    public static string MD5_HexConvert_Static(string input)
    {
        var inputBytes = Encoding.UTF8.GetBytes(input);
        var hashBytes = MD5.HashData(inputBytes);
        return Convert.ToHexString(hashBytes);
    }

    private const int LOOPCOUNT = 100_0000;
    private static void CalcTime(Func<string, string> func, bool parallel = true)
    {
        Stopwatch stopwatch = Stopwatch.StartNew();

        if (parallel)
        {
            Parallel.For(0, LOOPCOUNT, i =>
            {
                func("123456");
            });
        }
        else
        {
            for (int i = 0; i < LOOPCOUNT; i++)
            {
                func("123456");
            }
        }

        stopwatch.Stop();
        Console.WriteLine($"{func.Method.Name,32}: {stopwatch.ElapsedMilliseconds,4}ms");
    }

    static void Main()
    {
        Test();

        Console.ReadKey();
    }

    private static void Test()
    {
        var functions = new List<Func<string, string>>
        {
            Md5_StringConcat,
            Md5_StringBuilder,
            Md5_BitConverter,
            MD5_HexConvert_Instance,
            MD5_HexConvert_Static,
        };

        foreach (var func in functions)
        {
            Console.WriteLine($"{func.Method.Name,32}: {func("123456")}");
        }

        Console.WriteLine($"\n单线程 {LOOPCOUNT} 次用时统计:");
        foreach (var func in functions)
        {
            CalcTime(func, false);
        }


        Console.WriteLine($"\n多线程 {LOOPCOUNT} 次用时统计:");
        foreach (var func in functions)
        {
            CalcTime(func, true);
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • BitConverter 版本
  • StringConcat 版本
  • 性能对比
  • Convert.ToHexString 实例版本
  • MD5.HashData 静态版本(强烈建议)
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档