当前位置: 首页 > ai >正文

crc16是什么算法

核心概念

CRC16​ 是一种循环冗余校验算法,属于哈希函数的一种。它的核心目的是检测数据的错误,通常用于数字网络和存储设备中,来验证数据在传输或存储后是否依然完整、无误。

你可以把它想象成一个数据的“指纹”或“摘要”。发送方计算出一段数据的 CRC16 值并随数据一起发送,接收方在收到数据后同样计算 CRC16 值。如果两个值相同,则认为数据在传输过程中极大概率没有出错;如果不同,则肯定发生了错误,数据需要重传。

算法原理(通俗版)

CRC16 的计算过程可以类比于一种特殊的“除法”,但不是在数字上做除法,而是在二进制位上做。

  1. 选定一个除数​:这个除数是一个固定的、预先定义好的二进制数,称为 ​​“生成多项式”​。不同的多项式会产生不同的CRC校验结果,从而形成了不同的CRC16标准(如CRC-16-CCITT、CRC-16-MODBUS等)。这个除数通常被称为 ​​“Poly”​

    • 例如,一个常用的多项式是 0x1021(十六进制表示),其二进制为 1 0000 0010 0001(共17位)。

  2. 准备被除数​:在原始数据的末尾添加一串 0(零),添加的 0的数量等于 CRC 值的长度(CRC16就是16位,所以添加16个0)。这个新组成的数就是“被除数”。

  3. 执行“除法”​​:

    • 将“被除数”与“生成多项式”对齐。

    • 进行 ​​“模2除法”​​(也叫“异或除法”)。这种除法的特点是:它不看商是多少,只看余数;并且每一步的减法操作不借位,实际上就是进行异或(XOR)运算

    • 用生成多项式(除数)对数据的前几位进行异或操作,得到一个结果,然后向右“滑动”一位,继续处理后续的数据位。

  4. 得到余数​:经过整个“除法”过程后,最终得到的余数就是 ​CRC16 校验值。这个余数的长度肯定会小于除数的长度(即16位),所以它是一个16位的值,通常用4个十六进制数字表示(如 0xC3A7)。

关键点​:这个计算过程可以通过硬件电路(由移位寄存器和异或门组成)高效实现,也可以通过软件查表法来极大提升速度,因此非常适合在通信协议中快速使用。


主要特点

  • 检测错误能力​:CRC16 能有效检测出:

    • 所有单比特错误。

    • 所有的双比特错误(只要多项式选择得当)。

    • 任何奇数位的错误。

    • 大多数突发性错误(连续多位错误)。

  • 非加密​:CRC是校验码,不是加密哈希​(如MD5, SHA)。它的目的是检测无意的、随机的错误,而不是防止有意的篡改。它非常容易反向计算和伪造。

  • 输出长度固定​:无论输入数据多长,输出永远是16位(2字节)。

  • 计算速度快​:硬件和优化的软件实现都非常高效。


常见的 CRC16 标准

“CRC16”是一个统称,具体使用哪种取决于生成多项式、初始值、输入输出是否反转等参数。最常见的几种是:

  1. CRC-16-CCITT (XMODEM)​

    • 多项式: 0x1021(正常形式)

    • 初始值: 0x0000

    • 常用于XMODEM协议、蓝牙、PC串口等。

  2. CRC-16-CCITT (KERMIT) / CRC-16-MODBUS

    • 多项式: 0x1021

    • 注意​:Kermit和MODBUS版本在初始值和反转规则上与XMODEM不同。MODBUS是工业领域极其常见的标准。

    • MODBUS参数:初始值 0xFFFF,输入输出都反转。

  3. CRC-16-USB

    • 多项式: 0x8005(另一种常见形式)

    • 初始值: 0xFFFF

    • 用于USB数据包校验。

重要提示​:正因为参数不同,在开发时必须明确约定使用哪一种CRC16变体,否则通信双方计算出的校验码会不一致,导致通信失败。


简单示例

假设我们有一个简单的数据 0x01, 0x02,使用最简单的参数(初始值0)计算。

  1. 数据二进制: 00000001 00000010

  2. 后面加16个0: 00000001 00000010 00000000 00000000

  3. 用多项式 0x1021(二进制: 0001000000100001) 对这个长长的数进行模2除法。

  4. 最终会得到一个16位的余数,比如(假设的)0xE2F1

这个 0xE2F1就是CRC16校验码,它会跟随数据 0x01, 0x02一起被发送出去。

总结

CRC16​ 是一种高效、可靠的错误检测算法,通过一种特殊的二进制除法得到数据的16位“指纹”。它广泛应用于网络通信(如MODBUS)、数据存储(如ZIP文件)等场景,以确保数据的完整性。在使用时,最关键的是要确保通信双方采用完全相同的CRC16标准参数。

你可以使用在线的CRC计算器或编程语言中的相关库(如Python的crcmod、C#的System.IO.Hashing.Crc32等)来轻松计算它。

http://www.xdnf.cn/news/18649.html

相关文章:

  • C++ 指针与引用面试深度解析
  • STM32项目分享:基于STM32的智能洗衣机
  • 开源大模型天花板?DeepSeek-V3 6710亿参数MoE架构深度拆解
  • 微软恶意软件删除工具:官方免费的系统安全防护利器
  • 网络编程1-基本概念、函数接口
  • 2.1.5 数学与其他
  • VUE 的弹出框实现图片预览和视频预览
  • C++数据结构之二叉搜索树
  • AEB 强制来临,东软睿驰Next-Cube-Lite有望成为汽车安全普惠“破局器”
  • macbook国内源安装rust
  • 【AGI使用教程】GPT-OSS 本地部署(2)
  • 【AMBA总线互联IP】
  • 自然语言处理——07 BERT、ELMO、GTP系列模型
  • python文件import找不到其它目录的库解决方案
  • Python爬虫第四课:selenium自动化
  • 【云馨AI-大模型】AI热潮持续升温:2025年8月第三周全球动态
  • MySQL数据库精研之旅第十一期:打造高效联合查询的实战宝典(二)
  • 禁用 Nagle 算法(TCP_NODELAY)
  • RuoYi-Vue3项目中Swagger接口测试404,端口问题解析排查
  • 信誉代币的发行和管理机制是怎样的?
  • linux下camera 详细驱动流程 OV02K10为例(chatgpt版本)
  • stm32温控大棚测控系统(CO2+温湿度+光照)+仿真
  • Linux->多线程2
  • 56 C++ 现代C++编程艺术5-万能引用
  • Wagtail CRX 简介
  • 详解无监督学习的核心原理
  • vscode配置remote-ssh进行容器内开发
  • Linux服务测试题(DNS,NFS,DHCP,HTTP)
  • 微服务-21.网关路由-路由属性
  • 零基础玩转STM32:深入理解ARM Cortex-M内核与寄存器编程