这是一个普遍的问题,本身md5在实现的时候方式就很多,结果还不一致,更别谈跨语言了,今天把两种各自试了一下,结论如下
1,32位的加密一定要选字符编码,并且通过与java的测试,发现除了utf8,ascii和default(default对应java的gbk,但这个应该取决于当前操作系统)这几种编码方式,其它的编码方式输出的结果一个都对不上
2,16位在C#不过是32位里面截取了一小段
3,想要C#和Java,以及其它语言各自md5后能互相识别,那还是在编码的时候选择utf8吧,当然你一定要用ascii和gbk也可以,但是你得知道,C#里面找个gbk都难找,除非你知道它的code page(http://msdn.microsoft.com/en-us/library/system.text.encoding.codepage.aspx),为了避免麻烦,还是用通行的utf8吧
用C#写了一个控制台应用,把结果输出在后面了,各种语言可以自己去对照,英文用的是zkx,中文用的是中科信
using System; using System.Security.Cryptography; using System.Text; using System.Web.Security; namespace temp { class Program { static void Main(string[] args) { Console.WriteLine("=======zkx=========="); Console.WriteLine("utf8:"+MD5_32("zkx")); Console.WriteLine("default: "+MD5_32("zkx", Encoding.Default)); Console.WriteLine("ascii: "+MD5_32("zkx", Encoding.ASCII)); Console.WriteLine("unicode: "+MD5_32("zkx", Encoding.Unicode)); Console.WriteLine("utf32: "+MD5_32("zkx", Encoding.UTF32)); Console.WriteLine("utf7: " + MD5_32("zkx", Encoding.UTF7)); Console.WriteLine("========中科信========="); Console.WriteLine("utf8:" + MD5_32("中科信")); Console.WriteLine("default: " + MD5_32("中科信", Encoding.Default)); Console.WriteLine("ascii: " + MD5_32("中科信", Encoding.ASCII)); Console.WriteLine("unicode: " + MD5_32("中科信", Encoding.Unicode)); Console.WriteLine("utf32: " + MD5_32("中科信", Encoding.UTF32)); Console.WriteLine("utf7: " + MD5_32("中科信", Encoding.UTF7)); Console.WriteLine("============="); Console.WriteLine("zkx@16\t" + MD5_16("zkx")); Console.WriteLine("zkx@16\t" + MD5_16b("zkx")); Console.WriteLine("zkx@16\t" + MD5_web("zkx")); Console.WriteLine("中科信@16\t" + MD5_16("中科信")); Console.WriteLine("中科信@16\t" + MD5_16b("中科信")); Console.WriteLine("中科信@16\t" + MD5_web("中科信")); Console.WriteLine("================"); Console.WriteLine("zkx@16\t" + Encrypt("zkx")); Console.WriteLine("中科信@16\t" + Encrypt("中科信")); } static string MD5_32(string input) { return MD5_32(input, null); } /// <summary> /// MD5 32位加密 /// </summary> /// <param name="input">源字符串</param> /// <param name="encoding">字符编码,默认(传入null)为UTF8</param> /// <returns></returns> static string MD5_32(string input,Encoding encoding) { if (encoding==null) { encoding = Encoding.UTF8; } //using (MD5CryptoServiceProvider md5Hash = new MD5CryptoServiceProvider()) using (MD5 md5Hash = MD5.Create()) { // Convert the input string to a byte array and compute the hash. byte[] data = md5Hash.ComputeHash(encoding.GetBytes(input)); // Create a new Stringbuilder to collect the bytes // and create a string. StringBuilder sBuilder = new StringBuilder(); // Loop through each byte of the hashed data // and format each one as a hexadecimal string. for (int i = 0; i < data.Length; i++) { sBuilder.Append(data[i].ToString("x2")); } // Return the hexadecimal string. return sBuilder.ToString(); } } /// <summary> /// MD5 16位加密 加密后密码为大写 /// </summary> /// <param name="input"></param> /// <returns></returns> public static string MD5_16(string input) { using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()) { string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(input)), 4, 8); t2 = t2.Replace("-", ""); return t2; } } /// <summary> /// MD5 16位加密 加密后密码为大写 /// </summary> /// <param name="input"></param> /// <returns></returns> public static string MD5_16b(string input) { using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()) { return BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(input)), 4, 8); } } public static string MD5_web(string input) { return FormsAuthentication.HashPasswordForStoringInConfigFile(input, "MD5"); } //等于MD5_32方法每两位加一个短横线 public static string Encrypt(string password) { ///获取Byte数组 ///显然,此处也是根据不同的字符编码产生不同的输出的,MD5_32方法演示过,此处不再封装成变量了 Byte[] clearBytes = Encoding.Unicode.GetBytes(password); ///获取Hash值 Byte[] hashedBytes = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(clearBytes); ///获取加密后的信息 return BitConverter.ToString(hashedBytes); } } }
输出: