MD5的C#和Java同步

这是一个普遍的问题,本身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);
        }
    }
}

输出:

image

原文地址:https://www.cnblogs.com/walkerwang/p/2615718.html