IEEE802.3中的CRC32算法
IEEE802.3中的CRC32算法
- IEEE802.3中的CRC32算法
- 一. 代码解析
- 二. IEEE 802.3 标准CRC32算法流程
- 三. 为什么要用0xEDB88320L ?
- 四. CRC码校验原理
一. 代码解析
CRC即循环冗余校验(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。
#include <stdio.h>
#include <stdint.h>
// 多项式除数 0xEDB88320
#define POLY 0xEDB88320UL
// 计算 CRC32 校验和
uint32_t crc32(const void *data, size_t len)
{
const uint8_t *bytes = data;
uint32_t crc = 0xFFFFFFFFUL;
// 循环处理每个字节
for (size_t i = 0; i < len; i++) {
crc ^= bytes[i]; // 把当前字节与 crc 的低 8 位进行异或操作
// 处理当前字节的 8 位,每次处理一位
for (int j = 0; j < 8; j++) {
if (crc & 1u) { // 如果 crc 的最低位为 1,则右移并与多项式除数进行异或操作
crc >>= 1;
crc ^= POLY;
} else { // 否则,只右移一个比特位
crc >>= 1;
}
}
}
return crc;
}
int main()
{
// 测试数据
char data[] = "123456789";
size_t len = sizeof(data) - 1; // 注意,字符数组中包含了一个字符串末尾的 NULL 结束符
// 计算 CRC32 校验和
uint32_t crc = crc32(data, len);
// 输出结果
printf("CRC32: 0x%08X\n", crc);
return 0;
}
这个hashCRC32函数用于计算给定长度的数据的CRC32校验和。
该函数有两个参数,分别为指向待计算数据的指针和数据的长度。0xEDB88320UL是多项式除数。
函数首先将多项式除数赋给一个32位的变量crc,然后对待校验数据的每个字节进行处理。
对于每个字节,函数先将其与crc变量的低8位进行异或操作,然后循环处理其8位二进制位,每次判断最低位是否为1,
如果是1,则将crc变量右移一位并与多项式除数进行异或操作,否则只将crc变量右移一位。
处理完所有字节后,得到最终的CRC32校验和。
二. IEEE 802.3 标准CRC32算法流程
IEEE 802.3 标准中规定的 CRC32 算法是一种基于多项式除法的校验和计算方法。在以太网中,每个帧都包括一个CRC32校验和字段,用于检测数据在传输过程中是否出现了错误。该算法使用的多项式除数为 0xEDB88320L,初始值为 0xFFFFFFFF。
具体来说,CRC32 算法首先将初始值赋给一个 32 位寄存器(在示例代码中是crc32变量),然后对待校验数据的每个字节进行处理。处理过程包括以下两个步骤:
- 将下一个字节与当前 CRC 寄存器的低 8 位进行异或操作。
- 对于 CRC 寄存器中的每一位,如果其数值为 1,则将寄存器右移一位并与多项式除数进行异或操作;否则只将寄存器右移一位。
处理完所有字节后,将最终得到的CRC寄存器中的值进行异或操作,即可得到最终的CRC32校验和。
三. 为什么要用0xEDB88320L ?
x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 多项式按正常写法是0x04C11DB7 ,翻转就是0xEDB88320了。
它被广泛应用于各种CRC32算法中,包括IEEE 802.3标准中规定的CRC32算法。
使用不同的多项式除数可以得到不同的 CRC32 校验和结果。因此,在设计具体应用时,需要根据实际需求选择合适的多项式除数。不过,由于历史原因以及兼容性等考虑,0xEDB88320L 成为了 CRC32 校验算法中最为常用的多项式除数之一。
在计算 CRC32 校验和时,除数通常被作为一个核心参数嵌入到算法中。它可以使CRC32算法具有很好的检错性能和误差容忍度,从而可以广泛应用于各种网络传输、存储校验等领域。
四. CRC码校验原理
-
发送端:发送端根据信息字段与生成多项式生成一个CRC码,CRC码作为数据发送给接收端,同时也会把计算出的校验字段的数据一同发送(注:目的是如果接受端检测到发送的数据是正确的,接收端能够从CRC码中提取出信息字段的数据)。
-
接收端:接收到CRC码数据后,检测接收到的数据是否正确,方法:将CRC码数据与生成多项式进行模2除,如果余数为0,则说明接收到的数据是正确的。然后,从CRC码中提取出信息字段的数据。