尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

校验码:只防意外,不防人

校验码:只防意外,不防人 你下载了一个文件打开发现数据是错的。不是下错了版本是传输过程中某个比特悄悄翻了个身。网线经过变电站旁边被干扰了一下Wi-Fi 穿墙丢了几帧——数据从 A 传到 B中间要经过线缆、无线电、磁盘、内存每个环节都可能出错。这就是校验要解决的问题。不是防人是防意外。校验和哈希长得很像都是把一段数据压缩成一个短值贴在原文后面。但目的完全不同——哈希防恶意碰撞校验防传输错误。哈希的设计前提是「有人会想办法攻击你」校验的设计前提是「没人攻击你但物理世界不靠谱」。这个区别决定了它们走完全不同的路。奇偶校验太简单了最早的校验是电报时代的奇偶校验。一个字节八个位末尾加一个校验位。约定这一串里 1 的个数永远是偶数。发送前填好收到后数一遍——对上了数据没错对不上有人翻了。但这个方案有个致命的盲区只防单比特错误。一个位翻了奇偶必变。两个位翻了奇偶不变——总数还是偶数校验位告诉你「没问题」数据已经错了。物理世界不会只翻一个位。电磁干扰是成片来的一根线被干扰上面跑的八个位随便翻几个。奇偶校验能发现第一个发现不了第二个和第三个。但它没退出历史。ECC 内存还在用这个思路——不只是发现错误还能纠正。一个比特翻了算出哪个位自己翻回去。这才是它的归宿不是通用数据传输是内存制造商替操作系统在硬件层兜底。校验和加一遍不够奇偶校验太容易漏。校验和换了个思路不数 1 的个数把数据当数字一段一段加起来末尾贴和。但这个算法有个更隐蔽的问题和不变不代表数据没变。传两个数100和200和是300。传过去翻了——100成了199200成了101和还是300。一增一减正好抵消。校验和告诉你「没问题」数据已经面目全非了。更坑的是字节顺序错了校验和也不变。100,200和200,100和一样但程序读到的顺序全反了。校验和的问题在于它假设错误是独立发生的——一个字节翻不翻跟邻居没关系。但物理世界的错误经常是抱团来的一段干扰同时掀翻好几个相邻字节。校验和管不了这个。CRC比加法聪明一点CRC 换了个思路不再做加法做除法。你传一串数据把它看成一个很长的数字。拿它除一个固定的除数余数就是 CRC 值。接收方用同一个除数再除一遍——余数对上了数据没错对不上中间有人翻了。为什么除法比加法强因为除法有放大效应改一个位余数全变不像加法那样能正负抵消。CRC-32 能抓到所有单比特错误、双比特错误、以及长度不超过 32 个比特的连续错误——这个覆盖范围加法做不到。但 CRC 强不强看的是你选的除数。除数选得好覆盖广选得不好漏一片。CRC 不是「即插即用」是「选对了除数才够用」。CRC 不是哈希别拿来当哈希用这是 CRC 最常见的翻车拿 CRC-32 当哈希函数用做数据去重做哈希分片。CRC 的数学结构决定了输入和输出之间有线性关系。哈希要求改一个位输出不可预测地全变——这叫雪崩效应。CRC 没有雪崩效应改一个位输出变但变化方式是可预测的。这意味着如果有人想攻击你给一个文件的 CRC 值他就能算出一个不同的文件也有同样的 CRC——不用暴力试直接算。故意构造碰撞CRC 拦不住。CRC 设计出来是防传输错误的不是防恶意攻击的。你用 CRC 做哈希分片攻击者可以构造一批文件全落到同一个片里——分片白分了。这不是 CRC 的 bug是它不该出现在这个场景。校验和哈希的边界校验只管「传输中比特有没有翻」哈希管「有没有人故意构造两个东西指向同一个输出」。碰错了场景工具不背锅选的人背。怎么选你只想快速验证文件完整性不防恶意——CRC-32。网络传输、ZIP 压缩包、TCP/IP 协议栈里都在用它。硬件支持生态全认。别拿来当哈希别拿来防篡改。你要防篡改、防恶意破坏——别用校验用哈希。SHA-256 才是这个战场的答案。CRC 没有雪崩效应攻击者可推算。你要防传输错误 纠错——Reed-Solomon 码、Turbo 码、LDPC 码。这些是校验的下一代不仅发现错了还能把错的改回来。二维码扫花了能读、CD 划了能放——不是校验没发现错是纠错码替你修了。大部分场景选 CRC-32。它用了三十年够用。但永远记得CRC 前面的 C 是 Cyclic循环不是 Cryptographic密码学。别把它放进任何攻击者可能参与的地方。校验是物理世界的兜底——它不防人只防传输意外。拿 CRC 当哈希用就是给攻击者留了个后门。
返回列表