为了防止数据在传输的时候丢失或被篡改,有了各种校验码。
每种CRC校验都有自己的多项式。每个多项式都有唯一对应的二进制。
CRC16就如果名字一样,校验码就是16位的 如果CRC32就是32位的。
原理就是 用一个数字(数据的二进制)去除一个特定的数字(多项式对应的二进制) 得到的余数就是CRC码。
检验的时候吧余数加入到原来的二进制中,若可以除的尽,则数据没有丢失。
下面是获取一个二进制数据的CRC16校验码的代码:
private static void getCRC16(byte[] message, ref byte[] crc16)
{
ushort crcFull = 0xffff; //寄存器初始化
byte crcHigh = 0xff, crclow = 0xff;
char crclast;
for (int i = 0; i < message.Length; i++) //把每一个字节都跑一次
{
crcFull = (ushort)(crcFull ^ message[i]); //用来和寄存器的数组异或一下
for (int j = 0; j < 8; j++)
{
crclast = (char)(crcFull & 0x0001); //把每次最后一位保存下来
crcFull = (ushort)((crcFull >> 1) & 0x7fff); //把最后一位排出去
if (crclast == 1) //如果排除出去的是1 那么就要进行异或了
crcFull ^= 0xA001;
}
}
crc16[1] = crcHigh &= (byte)(crcFull >> 8); //获取高八位的二进制
crc16[0] = crclow &= (byte)crcFull; //低八位
}
校验:
private static bool judgeCRC16(byte[] message)
{
ushort crcFull = 0xffff;
char crclast;
for(int i=0;i<message.Length;i++)
{
crcFull = (ushort)(crcFull ^ message[i]);
for(int j=0;j<8;j++)
{
crclast =(char) (crcFull & 0x0001);
crcFull = (ushort)((crcFull >> 1) & 0x7fff);
if (crclast == 1)
crcFull ^= 0xA001;
}
}
//if (crcFull == 0) //0x0012>>8 = 0x0000
// return true;
//else
// return false;
return (crcFull == 0);
}
水平有限,不服打我。