.net core中你的MD5用對了嗎?
本文的項目環(huán)境為 .net 6.0 (.net 5.0 以上都支持)
在 .net 中獲取字符串的 MD5 相信是非常容易的事情吧, 但是隨便在網上搜一搜發(fā)現(xiàn)流傳的版本還不少呢,比如:
-
StringBuilder版本(應該算是官方版本了,使用的人最多,我發(fā)現(xiàn)在 ABP 中也是使用的這個) -
BitConverter版本 -
StringConcat版本 (字符串拼接,用的人很少,估計都知道性能不好)
但是它們是否是最佳實現(xiàn)? 我們來測試一下
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;
}
性能對比
先上我測試得到的數(shù)據(jù)(本機配置: 4 核 8 線程, 測試結果可能不一致)

Benchmark

看結果,的確是字符串拼接性能最差,但是
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 靜態(tài)版本(強烈建議)
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 BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using System.Text;
using System.Security.Cryptography;
namespace ConsoleTest;
[SimpleJob(RuntimeMoniker.Net60)]
[MemoryDiagnoser(true)]
public class MD5_BenchMarks
{
[Params(10_0000)]
public int Size { get; set; }
[Benchmark]
[Arguments("123456")]
public 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();
}
[Benchmark]
[Arguments("123456")]
public 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;
}
[Benchmark]
[Arguments("123456")]
public 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("-", "");
}
[Benchmark]
[Arguments("123456")]
public 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);
}
[Benchmark]
[Arguments("123456")]
public string MD5_HexConvert_Static(string input)
{
var inputBytes = Encoding.UTF8.GetBytes(input);
var hashBytes = MD5.HashData(inputBytes);
return Convert.ToHexString(hashBytes);
}
}
class Program
{
static void Main()
{
BenchmarkRunner.Run(typeof(MD5_BenchMarks));
Console.ReadKey();
}
}

浙公網安備 33010602011771號