当前位置:编程学习 > C#/ASP.NET >>

C语言CRC校验代码转C# 谢谢!

最近在做一个com口的开发,协议居然是用CRC16校验,协议提供的是c语言的算法,麻烦个位帮忙给转下c# 呗,感激不尽!

可以用下面这个数据测试,倒数第2和第3个是检验值
A5 A5 A5 A5 A5 A5 A5 A5 01 00 00 80 00 00 00 00 00 00 51 00 0E 00 A1 05 01 09 00 01 50 30 30 30 44 00 00 00 7E 73 5A

这是协议上提供的 c语言 算法
#define CRC(crc,byte) (((crc) >> 8 ) ^ tabel[((crc) ^ (unsigned int) (byte)) & 0XFF]) static const uint16 tabel[256] = { 0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241, 0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440, 0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40, 0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841, 0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40, 0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41, 0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641, 0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040, 0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240, 0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441, 0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41, 0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840, 0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41, 0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40, 0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640, 0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041, 0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240, 0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441, 0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41, 0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840, 0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41, 0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40, 0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640, 0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041, 0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241, 0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40, 0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841, 0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40, 0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41, 0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641, 0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 };

unsigned short CalcCRC(data, size) char *data; int size; { int i; unsigned short crc = 0; for (i = 0; i < size; i++) { crc = CRC(crc, data[i]); } return crc; } --------------------编程问答--------------------

static const ushort table[256]={...};//照抄
ushort CRC(ushort crc,byte theByte)
{
    return (ushort)((crc >> 8 ) ^ tabel[(crc ^ (uint) (theByte)) & 0XFF]) ;
}

ushort CalcCRC(byte[] data,int size)
{
    int i;
    ushort crc=0;
    for(i=0;i<size;i++)
    {
         crc=CRC(crc,data[i]);
    }
    return crc;
}
--------------------编程问答--------------------
引用 1 楼 leafmao 的回复:

static const ushort table[256]={...};//照抄
ushort CRC(ushort crc,byte theByte)
{
    return (ushort)((crc >> 8 ) ^ tabel[(crc ^ (uint) (theByte)) & 0XFF]) ;
}

ushort CalcCRC(byte[] data,int size)
{
    int i;
    ushort crc=0;
    for(i=0;i<size;i++)
    {
         crc=CRC(crc,data[i]);
    }
    return crc;
}

我按你说的拷贝了一下代码,它报错,下面是我截的图。
--------------------编程问答-------------------- 不好意思,申明数组跟C有点混起来了
这样申明:

static const ushort [] table=new ushort[256]{...}; 
--------------------编程问答-------------------- 转换一下算法就可以了,我这里C、C#、VB、Delphi的都有 --------------------编程问答--------------------
 public class CrcITUTable
    {
        static ushort[] crctab16 = 
        {
            0X0000, 0X1189, 0X2312, 0X329B, 0X4624, 0X57AD, 0X6536, 0X74BF,
            0X8C48, 0X9DC1, 0XAF5A, 0XBED3, 0XCA6C, 0XDBE5, 0XE97E, 0XF8F7,
            0X1081, 0X0108, 0X3393, 0X221A, 0X56A5, 0X472C, 0X75B7, 0X643E,
            0X9CC9, 0X8D40, 0XBFDB, 0XAE52, 0XDAED, 0XCB64, 0XF9FF, 0XE876,
            0X2102, 0X308B, 0X0210, 0X1399, 0X6726, 0X76AF, 0X4434, 0X55BD,
            0XAD4A, 0XBCC3, 0X8E58, 0X9FD1, 0XEB6E, 0XFAE7, 0XC87C, 0XD9F5,
            0X3183, 0X200A, 0X1291, 0X0318, 0X77A7, 0X662E, 0X54B5, 0X453C,
            0XBDCB, 0XAC42, 0X9ED9, 0X8F50, 0XFBEF, 0XEA66, 0XD8FD, 0XC974,
            0X4204, 0X538D, 0X6116, 0X709F, 0X0420, 0X15A9, 0X2732, 0X36BB,
            0XCE4C, 0XDFC5, 0XED5E, 0XFCD7, 0X8868, 0X99E1, 0XAB7A, 0XBAF3,
            0X5285, 0X430C, 0X7197, 0X601E, 0X14A1, 0X0528, 0X37B3, 0X263A,
            0XDECD, 0XCF44, 0XFDDF, 0XEC56, 0X98E9, 0X8960, 0XBBFB, 0XAA72,
            0X6306, 0X728F, 0X4014, 0X519D, 0X2522, 0X34AB, 0X0630, 0X17B9,
            0XEF4E, 0XFEC7, 0XCC5C, 0XDDD5, 0XA96A, 0XB8E3, 0X8A78, 0X9BF1,
            0X7387, 0X620E, 0X5095, 0X411C, 0X35A3, 0X242A, 0X16B1, 0X0738,
            0XFFCF, 0XEE46, 0XDCDD, 0XCD54, 0XB9EB, 0XA862, 0X9AF9, 0X8B70,
            0X8408, 0X9581, 0XA71A, 0XB693, 0XC22C, 0XD3A5, 0XE13E, 0XF0B7,
            0X0840, 0X19C9, 0X2B52, 0X3ADB, 0X4E64, 0X5FED, 0X6D76, 0X7CFF,
            0X9489, 0X8500, 0XB79B, 0XA612, 0XD2AD, 0XC324, 0XF1BF, 0XE036,
            0X18C1, 0X0948, 0X3BD3, 0X2A5A, 0X5EE5, 0X4F6C, 0X7DF7, 0X6C7E,
            0XA50A, 0XB483, 0X8618, 0X9791, 0XE32E, 0XF2A7, 0XC03C, 0XD1B5,
            0X2942, 0X38CB, 0X0A50, 0X1BD9, 0X6F66, 0X7EEF, 0X4C74, 0X5DFD,
            0XB58B, 0XA402, 0X9699, 0X8710, 0XF3AF, 0XE226, 0XD0BD, 0XC134,
            0X39C3, 0X284A, 0X1AD1, 0X0B58, 0X7FE7, 0X6E6E, 0X5CF5, 0X4D7C,
            0XC60C, 0XD785, 0XE51E, 0XF497, 0X8028, 0X91A1, 0XA33A, 0XB2B3,
            0X4A44, 0X5BCD, 0X6956, 0X78DF, 0X0C60, 0X1DE9, 0X2F72, 0X3EFB,
            0XD68D, 0XC704, 0XF59F, 0XE416, 0X90A9, 0X8120, 0XB3BB, 0XA232,
            0X5AC5, 0X4B4C, 0X79D7, 0X685E, 0X1CE1, 0X0D68, 0X3FF3, 0X2E7A,
            0XE70E, 0XF687, 0XC41C, 0XD595, 0XA12A, 0XB0A3, 0X8238, 0X93B1,
            0X6B46, 0X7ACF, 0X4854, 0X59DD, 0X2D62, 0X3CEB, 0X0E70, 0X1FF9,
            0XF78F, 0XE606, 0XD49D, 0XC514, 0XB1AB, 0XA022, 0X92B9, 0X8330,
            0X7BC7, 0X6A4E, 0X58D5, 0X495C, 0X3DE3, 0X2C6A, 0X1EF1, 0X0F78,
       };

        public CrcITUTable()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
        /// <summary>
        /// 返回校验CRC-ITU
        /// </summary>
        /// <param name="pData">指针</param>
        /// <param name="nLength">指针偏移位数</param>
        /// <param name="crcCode"></param>
        /// <returns></returns>
        unsafe public static ushort GetCrcITU_T(byte* pData, int nLength, out string crcCode)
        {
            ushort fcs = 0xFFFF;
            ushort uRlt;
            string strTmp;
            while (nLength > 0)
            {
                fcs = (ushort)((ushort)(fcs >> 8) ^ crctab16[(fcs ^ *pData) & 0xFF]);
                nLength--;
                pData++;
            }

            uRlt = (ushort)~fcs;
            strTmp = uRlt.ToString("X4");
            crcCode = strTmp.Substring(0, 2) + strTmp.Substring(2, 2);

            return uRlt;
        }
        /// <summary>
        /// 验证CRC-ITU
        /// </summary>
        /// <param name="pData"></param>
        /// <param name="nLength"></param>
        /// <returns></returns>
        unsafe public bool IsCrcITUGood_T(byte* pData, int nLength)
        {
            ushort fcs = 0xFFFF;
            while (nLength > 0)
            {
                fcs = (ushort)((ushort)(fcs >> 8) ^ crctab16[(fcs ^ *pData) & 0xFF]);
                nLength--;
                pData++;
            }

            return (fcs == 0xF0B8);
        }

    }
--------------------编程问答-------------------- 使用

        /// <summary>
        /// CRC 校验,返回校验结果
        /// </summary>
        /// <param name="STR_CRC">需校验的值</param>
        /// <param name="STR_CON">对比值</param>
        /// <returns></returns>
        unsafe public static bool IsPassCRC_ITU(string STR_CRC,string STR_CON)
        {
            //在进一步操作之前先验证数据的正确性(CRC-ITU)
            //login ex:   78 78 0D 01 0868120106956821 0008 2624 0D0A    0D0108681201069568210008 CRC-ITU=> 2624
            //gps/lbs ex: 78 78 1F120D07160F2B34CB026AFDA40C38D38000140001CC00263800111D001F 916B 0D0A

            //YELLOW 2013/07/24  需要校验的数据每个不同,需区别对待

            byte[] buffer = Pub.strToToHexByte(STR_CRC);

            fixed (byte* btSrc = buffer)
            {
                CrcITUTable.GetCrcITU_T(btSrc, buffer.Length, out Crc);
            }

            if (Crc == STR_CON)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// CRC验证结果
        /// </summary>
        /// <param name="STR_SRC"></param>
        /// <returns></returns>
        unsafe public static string RET_CRC_VALUE(string STR_SRC)
        {
            //"0501" + src.Substring(20, 4)
            byte[] buffer = Pub.strToToHexByte(STR_SRC);

            fixed (byte* btSrc = buffer)
            {
                CrcITUTable.GetCrcITU_T(btSrc, buffer.Length, out Crc);
            }
            return Crc;
        }
--------------------编程问答-------------------- 因用到了指针,所以需要工程设置成允许unsafe编译。
有问题再问。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,