最近在ASP.NET项目中用到的,主要是对用户密码进行哈希加密,传统编程进行的两种哈希加密方式一般如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | using System; using System.Text; using System.Security.Cryptography; namespace ConsoleApplication1 { class Program { public static string ComputeSHA1Hash(string str) { using (SHA1CryptoServiceProvider sha1Csp = new SHA1CryptoServiceProvider()) { str = Convert.ToBase64String( sha1Csp.ComputeHash( Encoding.UTF8.GetBytes(str) ) ); sha1Csp.Clear(); } return str; } public static string ComputeMD5Hash(string str) { using (MD5CryptoServiceProvider md5Csp = new MD5CryptoServiceProvider()) { str = Convert.ToBase64String( md5Csp.ComputeHash( Encoding.UTF8.GetBytes(str) ) ); md5Csp.Clear(); } return str; } static void Main(string[] args) { System.Console.WriteLine(ComputeSHA1Hash(@"http://wangye.org")); System.Console.WriteLine(ComputeMD5Hash(@"http://wangye.org")); } } } |
通过代码可以很明显的看出,我们主要引入System.Security.Cryptography的命名空间,然后调用其SHA1CryptoServiceProvider进行SHA1哈希或者调用MD5CryptoServiceProvider进行MD5哈希,当然由于哈希所需要的参数是字节型的,所以还需要将字符串进行一次字节编码,为了更好的兼容性,我们这里选择Encoding.UTF8.GetBytes进行UTF8编码,然后将哈希编码好的字节码再转换为Base64,至此整个哈希编码完成。
大家可能看到这两个函数比较类似,有没有什么办法将它们整合一下,变得更通用呢?对了,你可能想到了反射(Reflection),确实我们可以引入反射机制,从而让我们的代码更精简,更通用。反射功能需要引入System.Reflection命名空间,然后查找SHA1CryptoServiceProvider和MD5CryptoServiceProvider的定义,发现其共同继承了HashAlgorithm这个类,这么说这个类可以作为一个通用的类型。Assembly.GetAssembly().CreateInstance()的方式创建对象,那么GetAssembly()的参数类型该如何获得呢?我们可以通过System.Type.GetType(“命名空间名称”)这个方法得到,比如说System.Type.GetType(“System.Security.Cryptography.SHA1CryptoServiceProvider”)将得到SHA1CryptoServiceProvider的类型,那么SHA1就可以独立出来,就像System.Type.GetType(“System.Security.Cryptography.”+param+”CryptoServiceProvider”),param如果是SHA1,那么就是SHA1的Provider,如果是MD5,那么就是MD5的Provider。恩,先简单介绍到这里,具体的代码如下: