using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Security.Cryptography;
using System.Web;
using System.Net.NetworkInformation;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Common
{
    public static class Tools
    {
        /// <summary>
        ///  时间戳转本地时间-时间戳精确到秒
        /// </summary> 
        public static DateTime ToLocalTimeDateBySeconds(long unix)
        {
            var dto = DateTimeOffset.FromUnixTimeSeconds(unix);
            return dto.ToLocalTime().DateTime;
        }

        /// <summary>
        ///  时间转时间戳Unix-时间戳精确到秒
        /// </summary> 
        public static long ToUnixTimestampBySeconds(DateTime dt)
        {
            DateTimeOffset dto = new DateTimeOffset(dt);
            return dto.ToUnixTimeSeconds();
        }


        /// <summary>
        ///  时间戳转本地时间-时间戳精确到毫秒
        /// </summary> 
        public static DateTime ToLocalTimeDateByMilliseconds(long unix)
        {
            var dto = DateTimeOffset.FromUnixTimeMilliseconds(unix);
            return dto.ToLocalTime().DateTime;
        }

        /// <summary>
        ///  时间转时间戳Unix-时间戳精确到毫秒
        /// </summary> 
        public static long ToUnixTimestampByMilliseconds(DateTime dt)
        {
            DateTimeOffset dto = new DateTimeOffset(dt);
            return dto.ToUnixTimeMilliseconds();
        }

        /// <summary>
        /// 生成CRC16校验
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static ushort CRC16(byte[] buffer, int len)
        {
            uint xda, xdapoly;
            byte xdabit;
            xda = 0xFFFF;
            xdapoly = 0xA001;	// (X**16 + X**15 + X**2 + 1)

            for (int i = 0; i < len; i++)
            {
                xda ^= buffer[i];
                for (int j = 0; j < 8; j++)
                {
                    xdabit = (byte)(xda & 0x01);
                    xda >>= 1;
                    if (xdabit == 1)
                    {
                        xda ^= xdapoly;
                    }
                }
            }
            return Convert.ToUInt16(xda & 0xffff);
        }

        /// <summary>
        /// 计算文件的MD5值
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static byte[] MD5(string file)
        {
            using (Stream stream = File.Open(file, FileMode.Open))
            {
                return MD5(stream);
            }
        }

        /// <summary>
        /// 计算流的MD5值
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static byte[] MD5(Stream stream)
        {
            using (MD5 md5 = new MD5CryptoServiceProvider())
            {
                return md5.ComputeHash(stream);
            }
        }
        /// <summary>
        /// 计算文件MD5
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static string ComputeFileHash(Stream stream)
        {
            byte[] retVal = Tools.MD5(stream);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            return sb.ToString();
        }

        /// <summary>
        /// 将MD5字符串转换成整型数组表示
        /// </summary>
        /// <param name="md5"></param>
        /// <returns></returns>
        public static uint[] MD5StringToUIntArray(string md5)
        {
            if (String.IsNullOrWhiteSpace(md5))
            {
                throw new ArgumentException("参数不能为空。", "md5");
            }

            try
            {
                uint[] md5Arr = new uint[4] { 0, 0, 0, 0 };

                md5Arr[0] = Convert.ToUInt32(md5.Substring(0, 8), 16);
                md5Arr[1] = Convert.ToUInt32(md5.Substring(8, 8), 16);
                md5Arr[2] = Convert.ToUInt32(md5.Substring(16, 8), 16);
                md5Arr[3] = Convert.ToUInt32(md5.Substring(24, 8), 16);

                return md5Arr;
            }
            catch (Exception ex)
            {
                throw new ApplicationException("转换MD5出错。", ex);
            }
        }
        /// <summary>
        /// 用MD5加密字符串
        /// </summary>
        /// <param name="str">待加密的字符串</param>
        /// <returns></returns>
        public static string MD5Encrypt(string str)
        {
            MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
            byte[] hashedDataBytes;
            hashedDataBytes = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(str));
            StringBuilder tmp = new StringBuilder();
            foreach (byte i in hashedDataBytes)
            {
                tmp.Append(i.ToString("x2"));
            }
            return tmp.ToString();
        }
        /// <summary>
        /// 获取指定长的的字符串对应的16进制字节码，如果长度不够，末位自动补0
        /// </summary>
        /// <param name="s"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static byte[] GetBytes(String str, int length)
        {
            byte[] s = System.Text.Encoding.GetEncoding("gb2312").GetBytes(str);
            int fixLength = length - s.Length;
            if (s.Length < length)
            {
                byte[] S_bytes = new byte[length];
                Array.Copy(s, 0, S_bytes, 0, s.Length);
                for (int x = length - fixLength; x < length; x++)
                {
                    S_bytes[x] = 0x00;
                }
                return S_bytes;
            }
            return s;
        }

        /// 获取一个随机数组
        /// </summary>
        /// <param name="num">数组个数</param>
        /// <param name="minValue"></param>
        /// <param name="maxValue"></param>
        /// <returns></returns>
        public static int[] GetRandomNum(int num, int minValue, int maxValue)
        {
            Random ra = new Random(unchecked((int)DateTime.Now.Ticks));
            int[] arrNum = new int[num];
            int tmp = 0;
            for (int i = 0; i <= num - 1; i++)
            {
                tmp = ra.Next(minValue, maxValue); //随机取数
                arrNum[i] = tmp;
            }
            return arrNum;
        }

        /// <summary>
        /// 字节内容转换为字符串
        /// </summary>
        /// <param name="bytesData"></param>
        /// <returns></returns>
        public static string ByteToString(byte[] bytesData)
        {
            StringBuilder result = new StringBuilder();
            foreach (byte r in bytesData)
            {
                result.Append(r.ToString("X2") + " ");
            }
            return result.ToString().Trim();
        }
        /// <summary>
        /// 把int32类型的数据转存到2个字节的byte数组中
        /// </summary>
        /// <param name="m">int32类型的数据</param>
        /// <param name="arry">2个字节大小的byte数组</param>
        /// <returns></returns>
        public static byte[] Int32ToByte(Int32 data)
        {
            byte[] arry = new byte[2];
            arry[0] = (byte)((data & 0xFF00) >> 8);
            arry[1] = (byte)(data & 0xFF);
            return arry;
        }
        /// <summary>
        /// 把int32类型的数据转存到2个字节的byte数组中：小端
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] Int32ToByte2(Int32 data)
        {
            byte[] arry = new byte[2];
            arry[0] = (byte)(data & 0xFF);
            arry[1] = (byte)((data & 0xFF00) >> 8);
            //arry[2] = (byte)((data & 0xFF0000) >> 16);
            //arry[3] = (byte)((data >> 24) & 0xFF);

            return arry;
        }
        /// <summary>
        /// 2位byte转换为int类型
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static int ByteToInt(byte[] data)
        {
            return (data[1] & 0xFF) << 8 | data[0];
        }
        /// <summary>
        /// 4位byte转换为long类型
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static long Byte4ToLong(byte[] data)
        {
            return (data[3] << 24) & 0xFF | (data[2] & 0xFF00) << 16 | (data[1] & 0xFF) << 8 | data[0];
        }
        /// <summary>
        /// long类型转换为4位byte
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] LongToByte4(long data)
        {
            byte[] arry = new byte[4];
            arry[0] = (byte)(data & 0xFF);
            arry[1] = (byte)((data & 0xFF00) >> 8);
            arry[2] = (byte)((data & 0xFF0000) >> 16);
            arry[3] = (byte)((data >> 24) & 0xFF);

            return arry;
        }

        /// <summary>   
        /// 得到字符串的长度，一个汉字算2个字符   
        /// </summary>   
        /// <param name="str">字符串</param>   
        /// <returns>返回字符串长度</returns>   
        public static int GetLength(string str)
        {
            if (str.Length == 0) return 0;

            ASCIIEncoding ascii = new ASCIIEncoding();
            int tempLen = 0;
            byte[] s = ascii.GetBytes(str);
            for (int i = 0; i < s.Length; i++)
            {
                if ((int)s[i] == 63)
                {
                    tempLen += 2;
                }
                else
                {
                    tempLen += 1;
                }
            }
            return tempLen;
        }

        /// <summary>
        /// HEX编码转换为——>ASCII编码
        /// </summary>
        /// <param name="Msg"></param>
        /// <returns></returns>
        public static string HexToASCII(string Msg)
        {
            byte[] buff = new byte[Msg.Length / 2];
            string Message = "";
            for (int i = 0; i < buff.Length; i++)
            {
                buff[i] = byte.Parse(Msg.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
            }
            System.Text.Encoding chs = System.Text.Encoding.ASCII;
            Message = chs.GetString(buff);
            return Message;
        }
        /// <summary>
        /// HEX编码转换为——>字符串
        /// </summary>
        /// <param name="Msg"></param>
        /// <returns></returns>
        public static string HexToStr(string Msg)
        {
            byte[] buff = new byte[Msg.Length / 2];
            string Message = "";
            for (int i = 0; i < buff.Length; i++)
            {
                buff[i] = byte.Parse(Msg.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
            }
            System.Text.Encoding chs = System.Text.Encoding.GetEncoding("gb2312");
            Message = chs.GetString(buff);
            return Message;
        }
        /// <summary>
        /// 字符串转化为——>HEX编码
        /// </summary>
        /// <param name="Msg"></param>
        /// <returns></returns>
        public static string StrToHex(string Msg)
        {
            byte[] bytes = System.Text.Encoding.Default.GetBytes(Msg);//转换为字节（十进制）
            string str = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                str += string.Format("{0:X}", bytes[i]);               //转换为十六进制
            }
            return str;
        }

        public static string GetCurrentTimeStamp()
        {
            TimeSpan ts = DateTime.Now.ToLocalTime() - new DateTime(1970, 1, 1, 8, 0, 0, 0, DateTimeKind.Utc);
            string current_timestamp = Convert.ToInt64(ts.TotalSeconds).ToString();
            return current_timestamp;
        }


        public static byte[] HEXString2ByteArray(string hexString)
        {
            char[] hexCharacters = hexString.ToCharArray();
            byte[] byteArray = new byte[hexCharacters.Length / 2];

            for (int i = 0; i < byteArray.Length; i++)
            {
                string hexVal = string.Concat(hexCharacters[i * 2], hexCharacters[i * 2 + 1]);
                byteArray[i] = Convert.ToByte(hexVal, 16);
            }
            return byteArray;

        }

        public static byte CombineBitsToByte(bool bit0, bool bit1, bool bit2, bool bit3)
        {
            byte result = (byte)((bit0 ? 1 : 0) << 3); // 将bit0移到第4位（高位）
            result |= (byte)((bit1 ? 1 : 0) << 2); // 将bit1移到第3位
            result |= (byte)((bit2 ? 1 : 0) << 1); // 将bit2移到第2位
            result |= (byte)(bit3 ? 1 : 0); // 将bit3移到第1位（低位）
            return result;
        }
    }
}
