首页 > 其他分享 >.net core中你的MD5用对了吗?

.net core中你的MD5用对了吗?

时间:2023-10-26 17:44:06浏览次数:36  
标签:hashBytes core string inputBytes var input net MD5

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

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

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

  2. BitConverter 版本

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

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

StringBuilder 版本

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 版本

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 版本

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 线程, 测试结果可能不一致)

image

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

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

  • Convert.ToHexString
  • MD5.HashData

Convert.ToHexString 实例版本

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 静态版本(强烈建议)

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, 这会导致 内存泄漏!!!

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

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

标签:hashBytes,core,string,inputBytes,var,input,net,MD5
From: https://www.cnblogs.com/broadm/p/17789951.html

相关文章

  • .Net6添加Swagger
    .Net6添加Swagger一.添加Swagger引用添加Swashbuckle.AspNetCore包二.使用Swagger1.新建TestController控制器[ApiController][Route("[controller]/[action]")]publicclassTestController:Controller{///<summary>///获取信息///</summary>......
  • 通讯 --- C# .NET CORE MQTT 心跳服务
    转自:https://www.cnblogs.com/hkzw/p/17689443.htmlMQTT服务可以自行学习,这里只是记录一下写的结果,粘贴即用。首先引入包 MQTTnet,注意这个包这里的代码是4.0一下版本我用的3.1.2版本的4.以上是另外的写法,该内容中4不支持我 直接下降版本到3.1.2可以了。如果你一......
  • .Net6 扩展Swagger
    .Net6扩展Swaggernet6集成了swagger的基础功能,但功能不够用因此只能自定义扩展方法了,如下1、集成Jwt授权将builder.Services.AddSwaggerGen();改成builder.Services.AddSwaggerGen(c=>{varscheme=newOpenApiSecurityScheme(){Description="......
  • 在CI/CD发布流水线中,使用dotnet publish命令编译.NET Core C#代码
    在搭建CI/CD发布流水线(例如Jenkins流水线)发布.NETCore项目时,我们需要在流水线中使用dotnetpublish命令来编译C#代码来生成DLL文件。参考dotnetpublish官方文档。其中这里有说到,dotnetpublish命令会隐式调用dotnetrestore命令来还原nuget包,所以调用dotnetpublish之前不用显......
  • ASP.NET Core 使用 MQTTnet 实现 MQTT 通讯协议
    转自:https://www.twle.cn/t/19383MQTT是啥呢?MQTT,英文全称 MessageQueuingTelemetryTransport,是一种基于 发布/订阅 模式的轻量级的消息传输协议,由IBM公司出品。物联网兴起后,MQTT因为够轻量,低带宽和低延时而被推上浪潮之巅。其实,MQTT几乎就是专门为网络受限设备、低......
  • 从Docker到Kubernetes
    1简介1.1什么是容器传统的虚拟化技术,比如VMWare,目标是创建完整的虚拟机。为了运行应用,除了部署应用本身及其依赖(通常几十MB),还得安装整个操作系统(几十GB)。如图所示,由于所有的容器共享同一个HostOS,这使得容器在体积上要比虚拟机小很多。另外,启动容器不需要启动整个操作系......
  • Kubernetes 100个常用命令
    转载https://mp.weixin.qq.com/s/pWj-ni5fuHLaK2AR-4gqqQ100个Kubectl命令,这些命令对于诊断Kubernetes集群中的问题非常有用。这些问题包括但不限于:• 集群信息• Pod诊断• 服务诊断• 部署诊断• 网络诊断• 持久卷和持久卷声明诊断• 资源......
  • EF Core无法翻译groupby等子查询
    烦人的表达式转化错误varquery1=emps.Grouby(v=>v.DeptId).Select(g=>new{DeptId=g.Key,Salary=g.Max(x=>x.Salary);varresult=fromdindeptsjoinqinquery1ond.Idequalsq.DeptIdselectnew{d.Name,q.Salary};上面代码运行起......
  • Centos7.0安装.core5.0步骤
    在线安装:1.将Microsoft包签名密钥添加到受信任密钥列表,并添加Microsoft包存储库:sudorpm-Uvhhttps://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm2.安装Asp.netCore运行时:sudoyuminstallaspnetcore-runtime-5.03.安装sdk:sudoyuminstal......
  • 【论文阅读笔记】【OCR-文本识别】 Towards Accurate Scene Text Recognition with Se
    SRNCVPR2020读论文思考的问题论文试图解决什么问题?如何利用文本的上下文语义信息来辅助文本识别任务RNN能部分利用语义信息,但它的利用方式是串行的,极大地限制了语义信息的帮助,会造成错误累积以及效率缓慢等问题文章提出了什么样的解决方法?提出全局语义理解......