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.mzph.cn/bicheng/68272.shtml

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

相关文章

# c语言:数组详解一

c语言&#xff1a;数组详解一 数组数组的概念引例&#xff1a;什么是数组数组的特征&#xff1a;下标&#xff08;索引&#xff09; 常用的数组按维度划分一维数组数组的定义&#xff1a;数组元素的访问数组的初始化**案例一、斐波拉契数列&#xff1a;****案例二、冒泡排序&am…

c#-Halcon入门教程——标定

Halcon代码 read_image (NinePointCalibration, D:/Desktop/halcon/ca74d-main/九点标定/NinePointCalibration.gif)rgb1_to_gray (NinePointCalibration, GrayImage)get_image_size (GrayImage, Width, Height) dev_display (GrayImage)* 获取当前显示的窗口句柄 dev_get_win…

语音识别的预训练模型

语音识别的预训练模型 语音识别模型 大致分为两类: 连接时序分类(Connectionist Temporal Classification, CTC):仅编码器(encoder-only)的模型,顶部带有线性分类(CTC)头序列到序列(Sequence-to-sequence, Seq2Seq):编码器-解码器(encoder-decoder)模型,编码器…

Kotlin 协程基础十 —— 协作、互斥锁与共享变量

Kotlin 协程基础系列&#xff1a; Kotlin 协程基础一 —— 总体知识概述 Kotlin 协程基础二 —— 结构化并发&#xff08;一&#xff09; Kotlin 协程基础三 —— 结构化并发&#xff08;二&#xff09; Kotlin 协程基础四 —— CoroutineScope 与 CoroutineContext Kotlin 协程…

4种革新性AI Agent工作流设计模式全解析

导读:AI Agent是指能够在特定环境中自主执行任务的人工智能系统,不仅接收任务,还自主制定和执行工作计划,并在过程中不断自我评估和调整,类似于人类在创造性任务中的思考和修正过程。AI Agent的四种关键设计模式是实现高效执行复杂任务的基础,共同构成了AI Agent的能力框…

Docker启动达梦 rman恢复

目录标题 1. 主库备份2. Docker启动备库3. 备库修改属组4. 开始恢复5. 连接数据库配置归档 & Open6. 检查数据 关于达梦数据库&#xff08;DMDBMS&#xff09;的主库备份、Docker启动备库、恢复备份以及配置归档和打开数据库的详细步骤。 1. 主库备份 # 使用达梦数据库备…

WPS excel使用宏编辑器合并 Sheet工作表

使用excel自带的工具合并Sheet表&#xff0c;我们会发现需要开通WPS会员才能使用合并功能&#xff1b; 那么WPS excel如何使用宏编辑器进行合并 Sheet表呢&#xff1f; 1、首先我们要看excel后缀是 .xlsx 还是 .xls &#xff1b;如果是.xlsx 那么 我们需要修改为 .xls 注…

MySQL之DDL语言

目录 一、数据库的基本操作 1、创建数据库 语法&#xff1a; 示例&#xff1a; 2、修改数据库 语法&#xff1a; 示例&#xff1a; 3、删除数据库 语法&#xff1a; 示例&#xff1a; 4、查询数据库 语法&#xff1a; 5、使用数据库 语法&#xff1a; 二、数据表…

js多种循环方法(通过循环进行判断的相关方法)

for&#xff1a;正常循环&#xff08;同步的循环&#xff09; break、continue终止循环 for (let index 0; index < array.length; index) {const element array[index];} forEach&#xff1a;正常循环&#xff08;异步的循环&#xff09; 通过try异常抛出终止循环&am…

RAG技术:是将知识库的文档和问题共同输入到LLM中

RAG技术 RAG技术是将知识库的文档和问题共同输入到LLM中 RAG技术是先从知识库中检索出与问题相关的文档片段,然后将这些检索到的文档片段与问题一起输入到LLM中进行回答。具体过程如下: 文本分块 由于LLM的上下文窗口有限,需要将长文本资料分割成较小的块,以便LLM能够有…

现代 CPU 的高性能架构与并发安全问题

现代 CPU 的设计&#xff08;如多级缓存、指令重排&#xff09;为了提升性能&#xff0c;引入了许多优化机制&#xff0c;但这些机制可能导致并发场景下的安全性问题。并发安全性主要体现在三个方面&#xff1a;原子性、有序性 和 可见性。这些问题在底层通过 CAS&#xff08;C…

SpringMVC框架(二)

目录 三、请求参数绑定 四、常用注解 1、RequestParam注解 2、RequestBody注解 3、RequestHeader注解 4、CookieValue注解 5、PathVaribale注解 三、请求参数绑定 1、案例 jsp代码 <% page contentType"text/html;charsetUTF-8" language"java"…

【Python项目】个人密码本文档系统

【Python项目】个人密码本文档系统 技术简介&#xff1a;采用Python技术、Django、MYSQL数据库等实现。 系统简介&#xff1a;系统主要的功能有&#xff08;1&#xff09;新建密码本&#xff1a;用户可以创建新的密码本来记录自己的账户与密码&#xff1b; &#xff08;2&#…

mysql连接失败问题记录

mysql服务有时候在未正常关闭时&#xff0c;会导致在机器重启后导致连接不成功&#xff0c;这边只记录我遇到的情况及解决方案&#xff0c;主要是mysql的日志文件在复位异常关闭时造成文件损坏&#xff0c;然后下一次开机MySQL可能无法正确读取或写入这些文件&#xff0c;从而导…

《OpenCV》——模版匹配

文章目录 OpenCV——模版匹配简介模版匹配使用场景OpenCV 中模板匹配的函数参数 OpenCV——模版匹配实例导入所需库读取图片并处理图片对模版图片进行处理进行模版匹配显示模版匹配的结果注意事项 OpenCV——模版匹配简介 OpenCV 是一个非常强大的计算机视觉库&#xff0c;其中…

doc、pdf转markdown

国外的一个网站可以&#xff1a; Convert A File Word, PDF, JPG Online 这个网站免费的&#xff0c;算是非常厚道了&#xff0c;但是大文件上传多了之后会扛不住 国内的一个网站也不错&#xff1a; TextIn-AI智能文档处理-图像处理技术-大模型加速器-在线免费体验 https://…

整数对最小和,暴力存储所有数组,再放容器sort一下,accumulate(s1.begin(),s2.begin()+k,0)即可。

#include <bits/stdc.h> using namespace std; //最小和问题&#xff0c;求出所有整数对求和&#xff0c;排序即可 int main() { int n1,n2; cin>>n1; int s1[n1]; for(int i0;i<n1;i) { cin>>s1[i]; } cin>>n…

金融项目实战 06|Python实现接口自动化——日志、实名认证和开户接口

目录 一、日志封装及应用&#xff08;理解&#xff09; 二、认证开户接口脚本编写 1、代码编写 1️⃣api目录 2️⃣script目录 2、BeautifulSoup库 1️⃣简介及例子 2️⃣提取html数据工具封装 3、认证开户参数化 一、日志封装及应用&#xff08;理解&#xff09; &…

浅谈云计算15 | 存储可靠性技术(RAID)

存储可靠性技术 一、存储可靠性需求1.1 数据完整性1.2 数据可用性1.3 故障容错性 二、传统RAID技术剖析2.1 RAID 02.2 RAID 12.3 RAID 52.4 RAID 62.5 RAID 10 三、RAID 2.0技术3.1 RAID 2.0技术原理3.1.1 两层虚拟化管理模式3.1.2 数据分布与重构 3.2 RAID 2.0技术优势3.2.1 自…

Spring官网构建Springboot工程

注意&#xff1a;基于Idea的 Spring Initializr 快速构建 SpringBoot 工程时需要联网。 1.进入SpringBoot官网 Spring | Home 点击QUICKSTART 点击start.spring.io进入spring initializr 2.选择依赖 3.生成工程 下载好后解压用IDEAD导入即可。