C++|CRC校验总结

参考:
Vector - CAPL - CRC算法介绍
开发工具 > CRC校验工具

文章目录

  • 简介
  • CRC-8
  • CRC-16
  • CRC-32

简介

循环冗余校验(Cyclic Redundancy Check,简称CRC)是一种数据校验算法,广泛用于检测数据传输或存储过程中的错误。它通过计算数据的校验和来检测数据是否在传输过程中发生了错误。以下是几种常用的CRC校验算法:
CRC-8

  • 多项式:常用的多项式有 0x07(x^8 + x^2 + x + 1)、0x31(x^8 + x^5 + x^4 + 1)等。
  • 应用:常用于简单的数据校验,如一些简单的通信协议中。

CRC-16

  • 多项式:常用的多项式有 0x8005(x^16 + x^15 + x^2 + 1)、0xA001(x^16 + x^13 + x^12 + x^11 + x^10 + x^8 + x^5 + x^2 + 1)等。
  • 应用:广泛用于各种通信协议和文件格式中,如Modbus协议、MPEG-2等。

CRC-32

  • 多项式:最常用的是 0x04C11DB7(x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1)。
  • 应用:广泛应用于网络协议(如以太网)、文件压缩(如ZIP文件)、文件系统(如FAT32)等。

CRC-64

  • 多项式:常用的多项式有 0x42F0E1EBA9EA3693(ECMA-182标准)等。
  • 应用:用于需要更高校验精度的场合,如大型文件的完整性校验。

CRC算法特点

  • 简单高效:CRC算法相对简单,计算速度快,适合实时数据传输校验。
  • 检测能力:能有效检测突发错误(burst errors),即连续的错误比特。
  • 可配置性:通过选择不同的多项式,可以适应不同的应用场景和错误检测需求。

CRC算法实现
CRC算法通常通过位操作实现,包括位移、异或等操作。对于不同的多项式和数据长度,可以预先计算出一个查找表(lookup table),以提高计算效率。例如,CRC-32算法在许多编程语言中都有现成的库函数可供使用。
CRC算法虽然能有效检测数据错误,但不能纠正错误,因此在需要纠错的场合,还需要结合其他纠错编码技术。

在CRC校验中常见的主要有CalculateCRC8、CalculateCRC8H2F、CalculateCRC16、CalculateCRC32、CalculateCRC32P4、CalculateCRC64。

CRC-8

宽度:8位 多项式:0x07 初始值:0x00 异或值:00


#include <iostream>
#include <vector>
#include <cstdint>template <typename Container>
static uint8_t calculateCRC8(const Container& data, int  len)
{uint8_t   InitCrc = 0x07;uint8_t crc = 0;int  i, j;for (i = 0; i < len; i++) {crc ^= data[i];for (j = 0; j < 8; j++) {if (crc & 0x80) {crc = (crc << 1) ^ InitCrc;}else {crc <<= 1;}}}return crc;
}int main()
{// 创建一个样本数据std::vector<uint8_t> data = { 0x01, 0x02, 0x03, 0x04, 0x05 };// 计算整个数据的 CRC8uint8_t crc = calculateCRC8(data,data.size());// 输出结果std::cout << "CRC8: 0x" << std::hex << static_cast<int>(crc) << std::endl;// 检查结果是否符合预期// 假设我们预期的 CRC8 值是 0x9Buint8_t expected_crc = 0xBC;if (crc == expected_crc) {std::cout << "CRC8 calculation is correct." << std::endl;}else {std::cout << "CRC8 calculation is incorrect." << std::endl;}
}

在这里插入图片描述

CRC-16

宽度:16位 多项式:0x07 初始值:0x00 异或值:00

#include <iostream>
#include <vector>
#include <cstdint>// 反转一个8位的值
uint8_t reverseBits(uint8_t value) {uint8_t result = 0;for (int i = 0; i < 8; i++) {result = (result << 1) | (value & 1);value >>= 1;}return result;
}template <typename Container>
static uint16_t calculateCRC16(const Container& data, int len) {// CRC-16多项式,x^16 + x^15 + x^2 + 1uint16_t polynomial = 0x8005;// CRC-16初始值uint16_t crc = 0x0000;int i, j;for (i = 0; i < len; i++) {// 反转数据字节uint8_t reversedData = reverseBits(data[i]);crc ^= static_cast<uint16_t>(reversedData) << 8;for (j = 0; j < 8; j++) {if (crc & 0x8000) {crc = (crc << 1) ^ polynomial;}else {crc <<= 1;}}}// 反转最终的CRC值crc = (crc >> 8) | (crc << 8);crc = reverseBits(static_cast<uint8_t>(crc & 0xFF)) | (reverseBits(static_cast<uint8_t>(crc >> 8)) << 8);return crc;
}int main() {// 创建一个样本数据std::vector<uint8_t> data = { 0x01, 0x02, 0x03, 0x04, 0x05 };// 计算整个数据的CRC-16uint16_t crc = calculateCRC16(data, data.size());// 输出结果std::cout << "CRC-16: 0x" << std::hex << crc << std::endl;// 检查结果是否符合预期// 假设我们预期的CRC-16值是0xXXXXuint16_t expected_crc = 0xbb0e; // 请根据实际情况替换为预期值if (crc == expected_crc) {std::cout << "CRC-16 calculation is correct." << std::endl;}else {std::cout << "CRC-16 calculation is incorrect." << std::endl;}
}

在这里插入图片描述

CRC-32

改了半天终于对了,可能和大小端有关系
从您的描述和计算结果来看,问题可能出在几个方面:

  1. 反向字节的顺序:在计算 CRC32 时,通常字节顺序和位顺序是反转的。即字节顺序按反向处理,而每个字节内的位也需要反转。
  2. 正确的 CRC32 算法实现:我们应该确保按标准的 CRC32 算法来进行处理。最常见的 CRC32 是基于 ISO 802.3
    标准,它的计算方法会要求从一个初始化值开始,对每个字节进行计算并使用最终的异或值。
  3. 字节处理顺序和位反转:需要确保数据和多项式都正确地按照字节顺序(小端序或大端序)来处理。
#include <iostream>
#include <vector>
#include <cstdint>
#include <iomanip> // 用于格式化输出const uint32_t CRC32_POLY = 0xEDB88320; // 反向多项式
const uint32_t CRC32_INIT = 0xFFFFFFFF; // CRC-32初始值
const uint32_t CRC32_XOR_OUT = 0xFFFFFFFF; // CRC-32最终异或值// CRC32查找表
uint32_t crc32Table[256];// 初始化CRC32查找表
void initCRC32Table() {for (uint32_t i = 0; i < 256; ++i) {uint32_t crc = i;for (uint32_t j = 8; j > 0; --j) {if (crc & 1) {crc = (crc >> 1) ^ CRC32_POLY;}else {crc >>= 1;}}crc32Table[i] = crc;}
}// 计算CRC32
uint32_t calculateCRC32(const std::vector<uint8_t>& data) {uint32_t crc = CRC32_INIT;for (size_t i = 0; i < data.size(); ++i) {uint8_t byte = data[i];crc = (crc >> 8) ^ crc32Table[(crc ^ byte) & 0xFF];}crc ^= CRC32_XOR_OUT;return crc;
}int main() {// 初始化CRC32查找表initCRC32Table();// 待校验的数据std::vector<uint8_t> data = { 0x01, 0x02, 0x03, 0x04, 0x05 , 0x06 };// 计算CRC-32校验值uint32_t crc = calculateCRC32(data);// 输出CRC-32校验值std::cout << "CRC-32: 0x" << std::hex << std::uppercase << std::setw(8) << std::setfill('0') << crc << std::endl;// 检查结果是否符合预期uint32_t expected_crc = 0x81F67724; // 预期的CRC-32值if (crc == expected_crc) {std::cout << "CRC-32 calculation is correct." << std::endl;}else {std::cout << "CRC-32 calculation is incorrect." << std::endl;}return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/2239.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

迅翼SwiftWing | ROS 固定翼开源仿真平台正式发布!

经过前期内测调试&#xff0c;ROS固定翼开源仿真平台今日正式上线&#xff01;现平台除适配PX4ROS环境外&#xff0c;也已实现APROS环境下的单机飞行控制仿真适配。欢迎大家通过文末链接查看项目地址以及具体使用手册。 1 平台简介 ROS固定翼仿真平台旨在实现固定翼无人机决策…

C语言数据结构与算法(排序)详细版

大家好&#xff0c;欢迎来到“干货”小仓库&#xff01;&#xff01; 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;无人扶我青云志&#xff0c;我自踏雪至山巅&#xff01;&#xff01;&am…

微信小程序获取openid

2025年1月15日&#xff1a; 注意&#xff1a;其中appid,secret&#xff0c;还有服务器网址都按自己实际的填写 1、先在云服务器上安装nodejs&#xff0c;然后写个get接口&#xff1a; const express require(express); const app express();app.get(/getOpenid,(req,res)&…

C语言:-三子棋游戏代码:分支-循环-数组-函数集合

思路分析&#xff1a; 1、写菜单 2、菜单之后进入游戏的操作 3、写函数 实现游戏 3.1、初始化棋盘函数&#xff0c;使数组元素都为空格 3.2、打印棋盘 棋盘的大概样子 3.3、玩家出棋 3.3.1、限制玩家要下的坐标位置 3.3.2、判断玩家要下的位置是否由棋子 3.4、电脑出棋 3.4.1、…

FPGA工程师成长四阶段

朋友&#xff0c;你有入行三年、五年、十年的职业规划吗&#xff1f;你知道你所做的岗位未来该如何成长吗&#xff1f; FPGA行业的发展近几年是蓬勃发展&#xff0c;有越来越多的人才想要或已经踏进了FPGA行业的大门。很多同学在入行FPGA之前&#xff0c;都会抱着满腹对职业发…

vscode的安装与使用

下载 地址&#xff1a;https://code.visualstudio.com/ 安装 修改安装路径&#xff08;不要有中文&#xff09; 点击下一步&#xff0c;创建桌面快捷方式&#xff0c;等待安装 安装中文插件 可以根据自己的需要安装python和Jupyter插件

懒饭 3.0.2 | 谷歌版纯净无广告教做菜软件

这款教做菜的软件是谷歌版&#xff0c;提供了一个纯净无广告的学习环境。即使没有会员&#xff0c;普通版也足够满足日常使用需求。软件内含分类和排行榜功能&#xff0c;支持搜索&#xff0c;教程形式多样&#xff0c;包括文字和视频&#xff0c;是学习烹饪技巧、追女朋友的好…

【数模学习笔记】插值算法和拟合算法

声明&#xff1a;以下笔记中的图片以及内容 均整理自“数学建模学习交流”清风老师的课程资料&#xff0c;仅用作学习交流使用 文章目录 插值算法定义三个类型插值举例插值多项式分段插值三角插值 一般插值多项式原理拉格朗日插值法龙格现象分段线性插值 牛顿插值法 Hermite埃尔…

计算机二级-Java系列(Java的特点)

java语言的特点 简单&#xff0c;面向对象&#xff0c;分布式&#xff0c;结构中立&#xff0c;可移植性&#xff0c;解释执行&#xff0c;健壮&#xff0c;安全&#xff0c;高性能&#xff0c;多线程和动态。 Java具有面向对象的三个基本特性为&#xff1a;封装&#xff0c;…

【Vue3 入门到实战】1. 创建Vue3工程

目录 ​编辑 1. 学习目标 2. 环境准备与初始化 3. 项目文件结构 4. 写一个简单的效果 5. 总结 1. 学习目标 (1) 掌握如何创建vue3项目。 (2) 了解项目中的文件的作用。 (3) 编辑App.vue文件&#xff0c;并写一个简单的效果。 2. 环境准备与初始化 (1) 安装 Node.js 和 …

vim使用指南

&#x1f3dd;️专栏&#xff1a;计算机操作系统 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 一、Vim 的基本概念 1.Vim 的主要模式&#xff1a; 1.1普通模式 (Normal Mode) 1.2插入…

TCP-IP详解卷 TCP的超时与重传

TCP-IP详解卷1-21&#xff1a;TCP的超时与重传&#xff08;Timeout and Retransmission&#xff09; 一&#xff1a;介绍 1&#xff1a; 与数据链路层的ARQ协议相类似&#xff0c;TCP使用超时重发的重传机制。 即&#xff1a;TCP每发送一个报文段&#xff0c;就对此报文段设置…

卷积神经02-CUDA+Pytorch环境安装

卷积神经02-CUDAPytorch环境安装 在使用Python进行pytorch的使用过程中遇到各种各样的版本冲突问题&#xff0c;在此进行记录 0-核心知识脉络 1&#xff09;根据自己电脑的CUDA版本安装对应版本的Pytorch&#xff0c;充分的使用GPU性能2&#xff09;电脑要先安装【CUDA ToolKi…

【STM32-学习笔记-7-】USART串口通信

文章目录 USART串口通信Ⅰ、硬件电路Ⅱ、常见的电平标准Ⅲ、串口参数及时序Ⅳ、STM32的USART简介数据帧起始位侦测数据采样波特率发生器 Ⅴ、USART函数介绍Ⅵ、USART_InitTypeDef结构体参数1、USART_BaudRate2、USART_WordLength3、USART_StopBits4、USART_Parity5、USART_Mode…

为深度学习创建PyTorch张量 - 最佳选项

为深度学习创建PyTorch张量 - 最佳选项 正如我们所看到的&#xff0c;PyTorch张量是torch.Tensor​ PyTorch类的实例。张量的抽象概念与PyTorch张量之间的区别在于&#xff0c;PyTorch张量为我们提供了一个可以在代码中操作的具体实现。 在上一篇文章中&#xff0c;我们看到了…

RabbitMQ(四)

SpringBoot整合RabbitMQ SpringBoot整合1、生产者工程①创建module②配置POM③YAML④主启动类⑤测试程序 2、消费者工程①创建module②配置POM③YAML文件内配置&#xff1a; ④主启动类⑤监听器 3、RabbitListener注解属性对比①bindings属性②queues属性 SpringBoot整合 1、生…

项目练习:若依管理系统字典功能-Vue前端部分

文章目录 一、情景说明二、若依Vue相关代码及配置1、utils代码2、components组件3、api接口代码4、Vuex配置5、main.js配置 三、使用方法1、html部分2、js部分 一、情景说明 我们在做web系统的时候&#xff0c;肯定会遇到一些常量选择场景。 比如&#xff0c;性别&#xff1a;…

【 PID 算法 】PID 算法基础

一、简介 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&#xff09;、Differential&#xff08;微分&#xff09;的缩写。也就是说&#xff0c;PID算法是结合这三种环节在一起的。粘一下百度百科中的东西吧。 顾名思义&#xff0c;…

微信小程序原生与 H5 交互方式

在微信小程序中&#xff0c;原生与 H5 页面&#xff08;即 WebView 页面&#xff09;之间的交互通常有以下几种方式&#xff1a; 1. 使用 postMessage 进行通信 微信小程序的 WebView 页面和原生小程序页面可以通过 postMessage 来进行数据传递。 WebView 页面向原生小程序发…

c++领域展开第十二幕——类和对象(STL简介——简单了解STL)超详细!!!!

文章目录 前言STL简介什么是STLSTL的版本STL的六大组件STL的重要性如何学习STL 总结 前言 上篇博客我们了解了初阶的模版函数&#xff0c;以及有关的一些使用方法。 今天我们来了解了解STL库的有关知识 跟我一起上车吧 STL简介 什么是STL STL&#xff1a;是C标准库的重要组成…