.net core中你的MD5用对了吗?
本文的项目环境为 .net 6.0 (.net 5.0 以上都支持)
在 .net 中获取字符串的 MD5 相信是非常容易的事情吧, 但是随便在网上搜一搜发现流传的版本还不少呢,比如:
StringBuilder版本(应该算是官方版本了,使用的人最多,我发现在 ABP 中也是使用的这个)BitConverter版本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 线程, 测试结果可能不一致)

看结果,的确是字符串拼接性能最差,但是
StringBuilder好像也不是很高效啊,那个什么 Static 是啥玩意,怎么性能这么好,相对于 StringBuilder, 单线程性能提高了 3 倍, 多线性提高了 5 倍???
没错,这就是我要说的, 从 .net 5.0 开始提供了 2 个非常高效的方法
Convert.ToHexStringMD5.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);
}
}
}
.net core中你的MD5用对了吗?的更多相关文章
- 在 ASP.NET Core 中执行租户服务
在 ASP.NET Core 中执行租户服务 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: http://gunna ...
- ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存
分享 最近在公司成功落地了一个用ASP.NET Core 开发前台的CMS项目,虽然对于表层的开发是兼容MVC5的,但是作为爱好者当然要用尽量多的ASP.NET Core新功能了. 背景 在项目开发的 ...
- Asp.Net Core中配置使用Kindeditor富文本编辑器实现图片上传和截图上传及文件管理和上传(开源代码.net core3.0)
KindEditor使用JavaScript编写,可以无缝的于Java..NET.PHP.ASP等程序接合. KindEditor非常适合在CMS.商城.论坛.博客.Wiki.电子邮件等互联网应用上使 ...
- 在Asp.Net Core中配置使用MarkDown富文本编辑器实现图片上传和截图上传(开源代码.net core3.0)
我们的富文本编辑器不能没有图片上传尤其是截图上传,下面我来教大家怎么实现MarkDown富文本编辑器截图上传和图片上传. 1.配置编辑器到html页 <div id="test-edi ...
- FormsAuthentication.HashPasswordForStoringInConfigFile方法再.net core中的替代代码
FormsAuthentication.HashPasswordForStoringInConfigFile()这个加密方法再.net core中不存在了,可以用下面的方式达到一样的加密效果 usin ...
- .NET Core中的认证管理解析
.NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...
- ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...
- Asp.net Core中使用Session
前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...
- 在ASP.NET Core中使用百度在线编辑器UEditor
在ASP.NET Core中使用百度在线编辑器UEditor 0x00 起因 最近需要一个在线编辑器,之前听人说过百度的UEditor不错,去官网下了一个.不过服务端只有ASP.NET版的,如果是为了 ...
- ASP.NET Core中的依赖注入(1):控制反转(IoC)
ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...
随机推荐
- Centos7配置fstp
Centos7配置fstp 1 创建用户 useradd -m -d /data/sftp_data/user1 -s /usr/sbin/nologin -g sftp user1 -m:自动创 ...
- 【原创】CPU性能优化小记
CPU性能优化小记 目录 CPU性能优化小记 一.现象 TOP各指标含义 二.分析 启动应用前 启动应用后 采集内核函数的方法 内核采集分析 火焰图分析 三.解决 一.现象 业务线反馈,单板只要一跑我 ...
- mysql的初体验——重装解决99%的问题
这两天被java_web的作业搞得头皮发麻,主要原因就是因为jdbc连接数据库一直失败,甚至差点把电脑搞崩,删个注册表,结果用户变量也被删了,心态直接炸裂.有以下几个地方,引以为戒: 1.配置环境最好 ...
- Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用
Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用 1. 什么是PhysicsRaycaster组件? PhysicsRaycaster是Unity UGUI中的 ...
- python2.7源码安装方式
安装python2.7 下载Python 2.7, 下载地址 解压安装 tar -xzvf Python-2.7.15.tgz cd Python-2.7.15 ./configure --prefi ...
- C# 多线程访问之 SemaphoreSlim(信号量)【进阶篇】
SemaphoreSlim 是对可同时访问某一共享资源或资源池的线程数加以限制的 Semaphore 的轻量替代,也可在等待时间预计很短的情况下用于在单个进程内等待. 由于 SemaphoreSlim ...
- Pythonre.compile:用于优化正则表达式匹配的工具
import re # Python re.compile的性能优势 # 相对于使用re.match和re.search等函数直接进行匹配,使用Python re.compile的优化方式可以带来更好 ...
- Web开发框架 WebBuilder 9 发布
WebBuilder 是一款强大,全面和高效的Web开发框架 .基于浏览器的集成开发环境,智能化的设计,能轻松完成常规桌面应用和面向手机等的移动应用开发.高效.稳定和可扩展的特点,适合复杂企业级应用的 ...
- CodeForces 1388D Captain Flint and Treasure
题意 给长度为\(n\)的序列\(a[n]\)和\(b[n]\),初始时\(ans=0\),有以下操作: \(ans=ans+a[i]\) 如果\(b[i]\neq-1\),则\(a[b[i]]=a[ ...
- [Python3] 初识py, 一个简单练手的小玩意. 快递查询
有图有真相 脚本代码 最近刚入门py, 准备写点小玩意练练手. 于是决定拿快递100开刀. 因为它的api很简单. # 快递100 API # 作者: 剑齿虎 # 邮箱: yuxiaobo64@gma ...