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;
}
我按你说的拷贝了一下代码,它报错,下面是我截的图。
--------------------编程问答-------------------- 不好意思,申明数组跟C有点混起来了
这样申明:
--------------------编程问答-------------------- 转换一下算法就可以了,我这里C、C#、VB、Delphi的都有 --------------------编程问答--------------------
static const ushort [] table=new ushort[256]{...};
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>--------------------编程问答-------------------- 因用到了指针,所以需要工程设置成允许unsafe编译。
/// 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;
}
有问题再问。
补充:.NET技术 , C#