• .net core中你的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 Liststring, 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);
            }
        }
    }
    
    
  • 相关阅读:
    “蔚来杯“2022牛客暑期多校训练营4 N.Particle Arts 规律 方差
    [VIM] MiniBufExplorer插件
    蓝牙BLE的一些理解
    python的N个案例之python pycharm环境搭建
    OpenCV实战(31)——基于级联Haar特征的目标检测
    新 树莓派4B 温湿度监测 基于debian12的树莓派OS
    【干货】Python注释快捷键
    TextChanged
    一键自动化博客发布工具,用过的人都说好(掘金篇)
    30V-STM32设计项目
  • 原文地址:https://www.cnblogs.com/broadm/p/17789951.html