1 CRC数学原理:多项式表示、模2除法、余数计算、初值与异或值的作用

1.1 多项式表示与GF(2)算术

CRC校验的核心是将二进制数据视为系数仅为0或1的多项式,在GF(2)有限域中运算。一个n位二进制数的多项式表示如下:

二进制多项式(最高幂次)说明
1011x³ + x¹ + x⁰系数从高位到低位对应幂次n-1 → 0
110101x⁵ + x⁴ + x² + x⁰缺位系数为0,不写项

GF(2)加法等效于异或,无进位无借位,减法与加法相同。例如:

多项式加法:x³ + x¹ + x⁰  
             + x³ + x²  
             = x² + x¹ + x⁰   (x³抵消)
二进制位运算:1011 ⊕ 1100 = 0111
关键概念:CRC使用的生成多项式(Generator Polynomial)是双方约定的除数,通常用十六进制简写。例如CRC-16-CCITT:x¹⁶ + x¹² + x⁵ + x⁰ → 0x1021。

1.2 模2除法与余数计算

CRC计算核心是模2除法(无借位除法)。步骤:

  1. 将待保护数据左移r位(r = 生成多项式最高幂次),附加r个0作为被除数。
  2. 用生成多项式(除数)按位异或(模2减)被除数高位,每次对齐多项式最高位。
  3. 重复直到处理完所有位,最后的余数(位数 < r)即为CRC校验值。

以下示例展示数据 1011 (x³+x+1) 使用生成多项式 1101 (x³+x²+1) 计算4位CRC的模2除法过程:

被除数:1011 000 (左移3位)
除数 :1101
运算:(对齐最高位)
  1011 000
⊕ 1101
  -----
  0110 000    (商的第一位1,余数移位)
  110 000     (对齐)
⊕ 1101
  -----
  001 000     (第二位商0,下移一位)
  01 000      (对齐)
⊕ 1101
  -----
  00 100      (第三位商0,下移一位)
  0 100       (对齐)
⊕ 1101
  -----
  0 001       (第四位商1,最后余数001)
最终余数:001 → CRC = 001
余数特征:余数位数严格少于生成多项式位数;若余数为0,表示数据无差错(暂不考虑初值影响)。

1.3 初值与异或值的作用

标准CRC算法引入初值(CRC寄存器初始值)和输出异或值,用于处理特定场景:

参数作用典型值(CRC-16-Modbus)
初值(Init)在计算前将CRC寄存器设置为非零值,避免前置0被忽略;使全0数据产生非零CRC。0xFFFF
输出异或值(XorOut)计算完成后将完整CRC寄存器与固定值异或,调整校验值分布。0x0000(不异或)

初值改变了计算过程的初始状态,输出异或值在最后一步做“显式翻转”。两者都是协议约定的标准化参数,蓝牙协议栈中常见CRC-16/CRC-32使用特定初值与异或值组合。

以CRC-16-IBM (初值0x0000, 异或0x0000) 与 CRC-16-Modbus (初值0xFFFF, 异或0x0000) 为例,相同数据产生不同校验值。

1.4 内联SVG:CRC计算流程与参数作用

CRC数学原理流程:多项式表示→模2除法→初值与异或值 数据多项式 二进制/多项式转换 左移r位(补0) r = 生成多项式最高幂 模2除法 每步异或对齐 生成多项式除数 初值(Init) 初始化CRC寄存器 影响 余数 < r位 CRC校验值(原始) 输出异或值(XorOut) 最终CRC CRC校验值 生成多项式示例 CRC-16-CCITT: x¹⁶+x¹²+x⁵+x⁰
易混淆点:初值在计算开始前写入寄存器,不是与结果异或;输出异或则是计算完成后对完整寄存器进行。两者顺序不可颠倒。蓝牙协议栈中CRC初值通常为0xFFFFFFFF(CRC-32)或0xFFFF(CRC-16),需查阅具体规范。

1.5 常见标准参数速查

算法生成多项式初值 (Init)输出异或 (XorOut)蓝牙应用
CRC-3204C11DB7 (x³²+...)0xFFFFFFFF0xFFFFFFFF蓝牙L2CAP、HCI数据包
CRC-16-CCITT0x10210x00000x0000蓝牙HCI命令事件
CRC-16-Modbus0x80050xFFFF0x0000蓝牙LL控制PDU

理解初值与异或值的物理意义:初值使得全0的数据产生非零CRC,避免遗漏前导0;输出异或用于调整CRC的统计分布,提高检错能力。在蓝牙基带中,这两项是强制的标准参数,不可随意修改。