CRC的用途
循环冗余校验码(CRC),是数据通讯领域最常用的差错校验码,相比于奇偶校验(PCC),检错能力更强,能检出多位错误。其特点是可以校验任意长度数据,生成任意长度校验码。
CRC计算原理
- 选择多项式 ,选择或者定义一个多项式,多项式的bit数=校验码bit数+1;
- 对要校验的数据进行左移填零 ,对需要校验的数据进行左移,左移空出来的bit用0填充,左移位数=校验码bit数;
- 对左移填零后的数据与多项式进行取余运算 ,取余时,将两个数据进行左对齐;
- 余数判断 ,对于上一步骤的余数进行判断,当余数位数大于校验码bit数时,重复第3步;当余数位数等于校验码bit数时,计算结束,该余数既为要计算的校验码。
模2运算
无进位的二进制算法
1.模2加法:0+0 =0,1+0 =1,0+1 =1,1+1=0。
2.模2减法:0-0 =0, 1-0 =1, 0-1 =1, 1-1=0。
3.模2乘法:00 =0,10 =0,01 =0,11=1。
4.模2除法:
图片:
多项式类型
多项式可以自己任意定义,是由1和0组成的一串二进制数
图片:
CRC-16 MODBUS
1多项式:x16+x15+x2+1 既0x8005
2初始值:0xFFFF,与初始值进行异或,既将数据按位进行翻转
C#计算代码
左移计算CRC,
该代码计算结果有问题,望大佬指正问题点
代码片
.
public ushort CalculateCRC(byte[] data, ushort initial, ushort polynomial)
{
ushort crc = initial;
for (int i = 0; i < data.Length; i++)
{
crc ^= (ushort)(data[i] << 8);
for (int j = 0; j < 8; j++)
{
if ((crc & 0x8000) != 0)
{
crc = (ushort)((crc << 1) ^ 0X8005);
}
else
{
crc <<= 1;
}
}
}
return crc;
}
右移计算CRC
此代码验证无问题
代码片
.
public ushort CalculateCRC(byte[] data, ushort initial, ushort polynomial)
{
ushort crc = initial;
ushort nShiftedBit ;
for (int i = 0; i < data.Length; i++)
{
crc ^= data[i] ;
for (int j = 0; j < 8; j++)
{
if ((crc & 0x1) == 1)
{
nShiftedBit=1;
}
else
{
nShiftedBit = 0;
}
crc >>= 1;
if (nShiftedBit != 0)
{
crc ^= 0xA001;
}
}
}
return crc;
}
参考文章
https://blog.csdn.net/tilblackout/article/details/131195357
https://blog.csdn.net/tilblackout/article/details/131198350