using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CRClib
{
    #region 16位CRC校验【CRC】

    /// <summary>
    /// 16位CRC校验
    /// </summary>
    internal class CRC
    {
        /// <summary>
        /// CRC校验,返回添加CRC校验码后的字符串
        /// 适用于485通讯，用于生成CRC校验码。输入16进制字符串；输出CRC校验码
        /// </summary>
        /// <param name="data">十六进制字符串</param>
        /// <returns>modbus-CRC校验码</returns>
        public static String CRCForModbus(string data)
        {
            //处理数字转换
            string sendBuf = data;
            string sendnoNull1 = sendBuf.Trim();//去掉字符串前后的空格
            string sendnoNull2 = sendnoNull1.Replace(" ", "");//去掉字符串中间的空格
            string sendNOComma = sendnoNull2.Replace(',', ' ');    //去掉英文逗号
            string sendNOComma1 = sendNOComma.Replace('，', ' '); //去掉中文逗号
            string strSendNoComma2 = sendNOComma1.Replace("0x", "");   //去掉0x
            data = strSendNoComma2.Replace("0X", "");   //去掉0X

            Byte[] crcbuf = strToHexByte(data);

            //计算并填写CRC校验码
            Int32 crc = 0xffff;
            Int32 len = crcbuf.Length;
            for (Int32 n = 0; n < len; n++)
            {
                Byte i;
                crc = crc ^ crcbuf[n];
                for (i = 0; i < 8; i++)
                {
                    Int32 TT;
                    TT = crc & 1;
                    crc = crc >> 1;
                    crc = crc & 0x7fff;
                    if (TT == 1)
                    {
                        crc = crc ^ 0xa001;
                    }
                    crc = crc & 0xffff;
                }
            }
            crc = ((crc & 0xFF) << 8 | (crc >> 8));//高低字节换位
            String CRCString = crc.ToString("X2");

            return (CRCString);
        }

        /// <summary>
        /// 16进制字符串转字节数组
        /// </summary>
        /// <param name="hexString">十六进制字符串</param>
        /// <returns>返回字节数组</returns>
        public static Byte[] strToHexByte(String hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString = hexString.Insert(hexString.Length - 1, 0.ToString());
            Byte[] returnBytes = new Byte[hexString.Length / 2];
            for (Int32 i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }


        
    }
    #endregion
}
