這是一個普遍的問題,本身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); } }}
輸出: