4

我有一些我正在审查的代码,用于将一些文本转换为MD5 Hash. 效果很好。MD5Hhash它用于为gravatar 头像创建一个。这里是 :-

static MD5CryptoServiceProvider md5CryptoServiceProvider = null;

public static string ToMD5Hash(this string value)
{
    //creating only when needed
    if (md5CryptoServiceProvider == null)
    {
        md5CryptoServiceProvider = new MD5CryptoServiceProvider();
    }

    byte[] newdata = Encoding.Default.GetBytes(value);
    byte[] encrypted = md5CryptoServiceProvider.ComputeHash(newdata);
    return BitConverter.ToString(encrypted).Replace("-", "").ToLower();
}

注意我们是如何MD5CryptoServiceProvider在第一次调用这个方法时创建的?(为了简单起见,这里不用担心比赛条件)。

我想知道,如果我将用于创建提供程序的行更改为这个...

using(var md5CryptoServiceProvider = new MD5CryptoServiceProvider())
{
    ... snip snip snip ....
}

现在,如何使用/使用这种方法?好吧,假设它是 StackOverflow 的主页 -> 为每个帖子生成用户的 md5 哈希,这样我们就可以生成他们的 gravatar url。所以视图可以调用这个方法几十次。

不要试图浪费太多时间来强调过早的优化等......哪个会更好?

4

4 回答 4

10

我会对线程安全更感兴趣...... MSDN 没有(除非我错过它)说这MD5CryptoServiceProvider是线程安全的,所以 IMO 最好的选择是每次通话都有一个......

得到错误答案的速度并不重要;-p

你可能不想做的(解决线程安全问题)是有一个静态实例并lock围绕它......当它可以在不同的请求上并行运行时,它将序列化你的所有加密代码。

于 2009-05-20T14:23:03.710 回答
4

测试它并计时。第一个性能更高,但可能并不重要。

using System;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;

namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch timer=new Stopwatch();
            int iterations = 100000;
            timer.Start();
            for (int i = 0; i < iterations; i++)
            {
                string s = "test" + i;
                string t=s.ToMd5Hash0();
            }
            timer.Stop();
            Console.WriteLine(timer.ElapsedTicks);

            timer.Reset();
            timer.Start();
            for (int i = 0; i < iterations; i++)
            {
                string s = "test" + i;
                string t = s.ToMd5Hash1();
            }
            timer.Stop();
            Console.WriteLine(timer.ElapsedTicks);

            Console.ReadKey();
        }
    }
    public static class Md5Factory
    {
        private static MD5CryptoServiceProvider md5CryptoServiceProvider;
        public static string ToMd5Hash0(this string value)
        {
            if (md5CryptoServiceProvider == null)
            {
                md5CryptoServiceProvider = new MD5CryptoServiceProvider();
            }
            byte[] newData = Encoding.Default.GetBytes(value);
            byte[] encrypted = md5CryptoServiceProvider.ComputeHash(newData);
            return BitConverter.ToString(encrypted).Replace("-", "").ToLower();
        }
        public static string ToMd5Hash1(this string value)
        {
            using (var provider = new MD5CryptoServiceProvider())
            {
                byte[] newData = Encoding.Default.GetBytes(value);
                byte[] encrypted = provider.ComputeHash(newData);
                return BitConverter.ToString(encrypted).Replace("-", "").ToLower();
            }
        }
    }
}
于 2009-05-20T14:49:29.633 回答
3

我希望现有代码会稍微快一些,因为它可以节省每次调用时重建 MD5CryptoServiceProvider,但我也希望时间由对 ComputeHash() 的调用支配。

于 2009-05-20T14:28:21.703 回答
2

我个人不明白为什么这两种方式都很重要,想想为了生成页面而必须运行的其他代码的捆绑。它的六个一个和六个其他的,无论哪种方式节省都将是微不足道的。

于 2009-05-20T14:28:39.237 回答