循环冗余校验(CRC,Cyclic Redundancy Check)是一种基于除法及余数的原理来进行错误侦测的算法。它的主要作用是在数据传输或保存后,检测可能出现的错误。以下是关于循环冗余校验算法的详细介绍:
- 工作原理:
- CRC算法将要发送的数据比特序列当作一个多项式m(x)的系数。在发送数据时,发送方使用双方预先约定的生成多项式G(x)去除这个数据多项式,求得一个余数多项式。
- 接着,发送方将余数多项式加到数据多项式之后,合成一个新的多项式A(x),并将其发送到接收端。
- 接收端在收到数据后,同样使用G(x)去除接收到的数据。如果计算结果与实际接收到的余数多项式数据相同,则表示数据传输正确;否则,表示存在错误。
- 校验码格式:
- CRC算法通过在要传输的k比特数据D后添加(n-k)比特冗余位(又称帧检验序列,Frame Check Sequence,FCS)F,形成n比特的传输帧T,再将其发送出去。
- 实际应用时,发送方和接收方在通信前约定好预设整数P。发送方在发送前通过一定的计算确定并填充F,然后发送。接收方收到数据后,进行result = T mod P运算,当且仅当result = 0时,接收方认为没有差错。
- 应用领域:
- CRC算法在数据通讯中是最常采用的校验方式,尤其在嵌入式软件开发中,经常要用到CRC算法对各种数据进行校验。
- CRC算法也广泛应用于计算机网络通信领域,用于检测数据传输或保存后可能出现的错误。例如,在无线电通信、SATA硬盘数据传输等系统中,CRC-32校验是最常用的检错手段之一。
- 优点:
- CRC算法检错能力强,容易实现,是应用最广的检错码编码方式之一。
- CRC算法利用软件进行校验,因此其检验速度很快,校验的误码率也较低,整个计算机网络通信的信息传输速度很高。
以下是一个用于计算数据块CRC(循环冗余校验)的算法实现:
static unsigned short ComputeBlockCrc(unsigned char *ptr, unsigned int dataSize, unsigned short cumulativeCrc)
{
unsigned int crc = cumulativeCrc; // 使用传入的累积CRC值作为初始值
unsigned char i;
while (dataSize--) {
for (i = 0x80; i != 0; i >>= 1) {
if ((crc & 0x8000) != 0) {
crc = (crc << 1) ^ 0x1021;
} else {
crc = crc << 1;
}
if ((*ptr & i) != 0) {
crc ^= 0x1021;
}
}
ptr++;
}
return (unsigned short)(crc & 0xFFFF); // 返回CRC的低16位
}