1. CRC 概述
循环冗余校验,英文叫 Cyclic Redundancy Check,简称 CRC。说实话,这名字有点吓人,但本质上它就是一个数学“指纹”算法——给你一串数据,算出一个固定长度的校验值,贴在数据后面。接收方用同样的方法再算一遍,如果算出的指纹跟收到的对得上,就说明数据大概率没被改过。
我最早接触 CRC 还是在刚入行做嵌入式的时候。当时调一个传感器模块,数据总是偶尔跳变,查了三天发现是传输线上的干扰把最后几个字节吃了,而刚好没做校验——从那以后,我所有串口通信必加 CRC。
1.1 到底什么是 CRC?
咱们抛开数学公式,用一个生活中的例子来理解。
- 想象你寄快递: 你有一盒积木(原始数据),你在盒子上贴一张纸条,纸条上写着“红色积木 5 块,蓝色积木 3 块……”(CRC 校验值)。
- 收件人收到后: 他打开盒子数一遍,再对比纸条上的数字,如果一致,说明快递没丢件。
- 如果是 CRC: 纸条上写的不是积木数量,而是用多项式除法算出来的一个余数。数据只要改一个 bit,余数几乎一定会变。
核心思想: CRC = 数据通过一个固定的“生成多项式”做二进制除法,得到余数(通常叫 FCS,Frame Check Sequence)。这个余数就是校验值。
你可能会问:“为什么不用简单的校验和(checksum)?” 我之前也这么想,后来在高速以太网项目里发现,简单的累加和太容易碰撞了,两个不同的数据可能算出同一个和。而 CRC 的数学特性决定了它几乎能 100% 检测出实际网络传输中最常见的突发错误。
| 对比项 | 校验和 (Checksum) | CRC |
|---|---|---|
| 计算方式 | 字节累加 / 异或 | 多项式除法(模 2 运算) |
| 检测能力 | 容易漏检 | 对突发错误有极高覆盖率 |
| 硬件开销 | 极低 | 适中(通常有专用硬件模块) |
| 典型场景 | IP 头校验、简单串口 | 磁盘、以太网、无线通信 |
1.2 历史演变:从 W. Wesley Peterson 到如今的工业标准
讲 CRC 的历史,绕不开一个人——W. Wesley Peterson。1961 年他在里首次提出了 CRC 的数学理论。不过他当时可能没想到,这东西会统治通信校验几十年。
- 1960s: 早期主要用于磁带存储和打孔纸带。我记得老一辈工程师提过,那时候用 CRC-12 校验 6 位字符,硬写出来的。
- 1970s: 随着 IBM 的同步串行协议出现,CRC-16 和 CRC-CCITT 被大量用于同步通信。
- 1980s – 1990s: Ethernet 标准选择了 CRC-32,直到今天几乎所有网卡都在用这个多项式。为什么选 32 位?因为当时 IBM 的 Ring 已经用了 CRC-32,IEEE 802.3 直接借鉴。
- 2000s 至今: 出现了 CRC-64 用于大规模存储(比如 ZFS 文件系统),还有各种变种多项式以适应不同场景。
一个小彩蛋: 你电脑里每一条以太网帧、每张硬盘扇区、每根 USB 线传输的数据,底层都可能在用 CRC。这技术已经 60 多岁了,但依然是最可靠的检错方式之一。
1.3 主要应用场景
平时工作中,CRC 几乎无处不在。我简单列几个最常碰到的:
- 数据存储: 硬盘的每个扇区末尾都有一块 CRC(或 ECC,但 ECC 也是基于 CRC 扩展的)。读数据时检查 CRC,能提前发现磁盘坏道。
- 网络通信: 以太网帧的 FCS 字段就是 CRC-32。WiFi、蓝牙、5G NR 都用 CRC。我在调试一个 WiFi 模块时曾碰到连续丢包,最后定位是 PCB 走线导致 CRC 频繁出错。
- 嵌入式通信: SPI、I2C、UART 等总线,很多协议栈会在应用层加 CRC。比如 Modbus RTU 就用 CRC-16。
- 文件校验: 你下载软件时看到的 SHA256 虽然更安全,但很多压缩包(比如 ZIP)内部还是用 CRC-32 来做快速完整性检查。
- 工业总线: CAN 总线用 CRC-15,Profibus 用 CRC-16。
我曾经踩过的坑: 有一回我把 CRC 的生成多项式搞反了——MSB 还是 LSB 先行没选对。结果收发两端算出来的值一直对不上,排查了两天,最终发现是软件里多项式配置的“初始值”和“输出异或”设错了。所以,用 CRC 时一定要确认好多项式、初始值、输出异或和输入数据反转这几个参数。
你看上面这个流程,发送方先做 CRC 计算,把结果(FCS)附在数据后面发出去。接收方收到后,用同样的多项式再做一次除法,看余数是不是零。如果是零,我基本可以放心,数据没被改过;如果不是零,那就丢弃重传。
一句话记忆: CRC 不是加密,不是纠错,它只是一种简单高效的检错手段。它能告诉你说“数据有问题”,但不会告诉你是哪一位有问题。纠错需要更复杂的算法(如汉明码、Reed-Solomon)。
好,这一章我们弄清楚了 CRC 是什么、怎么来的、用在哪。下一章我会带你拆解 CRC 的数学运算细节——别怕,我保证不用复杂的数学公式,咱们用二进制除法的思路来讲。
实践建议: 如果你手头有网络抓包工具(如 Wireshark),可以抓一条以太网帧,看帧尾的 4 个字节,那就是 FCS。对照着抓包内容,你就能建立直观的感觉。