using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Mall.Common.Plugin
{
    /// <summary>
    /// 加密方式
    /// </summary>
    public enum EncryptMode
    {
        /// <summary>
        /// 不加密
        /// </summary>
        None = 0,
        /// <summary>
        /// 16位MD5 -- (常规)
        /// </summary>
        MD5_16 = 1,
        /// <summary>
        /// 32位MD5
        /// </summary>
        MD5_32 = 3
    }

    /// <summary>
    /// 安全相关辅助类
    /// </summary>
    public class SecurityHelper
    {
        /// <summary>
        /// des 加密密码
        /// </summary>
        private static readonly string desKeyStr = "2019040812345678";

        #region MD5
        /// <summary>
        /// 使用32位MD5加密
        /// </summary>
        /// <param name="str">待加密字符串</param>
        /// <returns></returns>
        public static string MD5(string str)
        {
            return MD5(str, 32);
        }

        /// <summary>
        /// 使用MD5加密
        /// </summary>
        /// <param name="str">待加密字符串</param>
        /// <param name="code">加密位数  16 位 32 位</param>
        /// <returns></returns>
        public static string MD5(string str, int code)
        {
            if (code == 32)
                return MD5(str, 0, 32);
            else
                return MD5(str, 8, 16); //默认8-16位
        }

        /// <summary>
        /// 使用MD5加密
        /// </summary>
        /// <param name="str">待加密字符串</param>
        /// <param name="startIndex">截取的开始位置</param>
        /// <param name="endIndex">截取的结束</param>
        /// <returns></returns>
        private static string MD5(string str, int startIndex, int endIndex)
        {
            string sEncrypt = "";
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] result = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str));
            for (int i = 0; i < result.Length; i++)
            {
                sEncrypt += string.Format("{0:x}", result[i]).PadLeft(2, '0');
            }
            //16位MD5加密（取32位加密的9~25字符）
            return sEncrypt.ToLower().Substring(startIndex, endIndex);
        }


        /// <summary>
        /// 获取大写的MD5签名结果
        /// </summary>
        /// <param name="encypStr"></param>
        /// <param name="charset">默认值：utf-8</param>
        /// <returns></returns>
        public static string MD5EncryptWeChat(string encypStr, string charset = "")
        {
            var m5 = new MD5CryptoServiceProvider();
            //创建md5对象
            byte[] inputBye;
            //使用GB2312编码方式把字符串转化为字节数组．
            if (!string.IsNullOrWhiteSpace(charset))
            {
                inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
            }
            else
            {
                inputBye = Encoding.GetEncoding("utf-8").GetBytes(encypStr);
            }
            var outputBye = m5.ComputeHash(inputBye);
            var retStr = BitConverter.ToString(outputBye);
            retStr = retStr.Replace("-", "").ToUpper();
            return retStr;
        }
        #endregion


        #region DES
        /// <summary>
        /// Des解密(C#,java通用)
        /// </summary>
        /// <param name="encryptedString"></param>
        /// <returns></returns>
        public static string DesDecrypt(string encryptedString)
        {
            string keyString = desKeyStr.Substring(0, 8);
            byte[] btKey = Encoding.UTF8.GetBytes(keyString);
            byte[] btIv = Encoding.UTF8.GetBytes("12345678");
            var des = new DESCryptoServiceProvider();
            des.Mode = CipherMode.CBC;//这里指定加密模式为CBC
            des.Padding = PaddingMode.PKCS7;
            des.Key = btKey;
            des.IV = btIv;
            using (var ms = new MemoryStream())
            {
                byte[] inData = Convert.FromBase64String(encryptedString);
                using (var cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inData, 0, inData.Length);
                    cs.FlushFinalBlock();
                }
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }

        /// <summary>
        /// Des加密(C#,java通用)
        /// </summary>
        /// <param name="sourceString"></param>
        /// <returns></returns>
        public static string DesEncrypt(string sourceString)
        {
            string keyString = desKeyStr.Substring(0, 8);
            byte[] btIv = Encoding.UTF8.GetBytes("12345678");
            byte[] btKey = Encoding.UTF8.GetBytes(keyString);
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] inData = Encoding.UTF8.GetBytes(sourceString);
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIv), CryptoStreamMode.Write))
                {
                    cs.Write(inData, 0, inData.Length);
                    cs.FlushFinalBlock();
                }
                return Convert.ToBase64String(ms.ToArray());
            }
        }
        #endregion
    }
}