CRC校验

一:CRC概念

1.1、参考博客

参考的教程如下:

手算CRC及其实现

CRC校验算法原理分析

一文讲透CRC校验码-附赠C语言实例

CRC校验(手算与直观演示)

CRC(循环冗余校验)在线计算

1.2、什么是CRC

CRC(Cyclic Redundancy Checksum)是一种纠错技术,代表循环冗余校验和,可以认为在输入端根据一定的规则计算出来CRC checksum,编组到message信息中,发送到接收端。接收端根据相同的规则解码接收到的信息,如果接收到的CRC checksum与预期值相同,则说明得到的数据正确,否则异常。

CRC校验

下面接收CRC checksum如何获取:

这里需要知道几个组成部分或者说计算概念:多项式公式、多项式简记式(poly)、数据宽度、初始值(init)、结果异或值、输入值反转、输出值反转、参数模型。

1.3、多项式公式与简记式

对于CRC标准除数,一般使用多项式(或二项式)公式表示;

这里以CRC8作为介绍校验算法过程,CRC16和CRC32同理。

CRC8标准生成多项式

CRC-8 x8+x5+x4+1 0x31(0x131)
CRC-8 x8+x2+x1+1 0x07(0x107)
CRC-8 x8+x6+x4+x3+x2+x1 0x5E(0x15E)
注:由于多项式的最高为都为1,并且在代码的crc8计算中,最高位也是不使用的,
所以在多项式记录时都去掉了最高位。

实际计算也可以采用完整的多项式公式,但是这种会比较麻烦。所以我们实际代码使用的都是简记式;

1.4、计算过程

以CRC16为例计算:

1.根据CRC16的标准选择初始值(init)。

2.如果有输入反转,则将数据进行反转(如果没有输入反转,则跳过。默认的都是每一个字节按位反转)。

2.将反转后数据的第一个字节与初始值高8位异或。

3.判断最高位,若该位为 0 左移一位,若为 1 左移一位再与多项式异或。

4.重复3直至8位全部移位计算结束。

5.重复将所有输入数据操作完成以上步骤,所得16位数即16位CRC校验码。

6.如果有输出反转,则将CRC校验码进行反转(如果没有输出反转,则跳过。默认的都是整个数据按位反转)。

7.将反转后的CRC校验码与结果异或值得到最终的CRC校验码。

输入反转举例

以输入 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08为例说明输入反转的概念

反转得到的值为:0x80 0x40 0xc0 0x20 0xa0 0x60 0xe0 0x10

输出反转举例

0x5ceeac03输出反转值为0xc035773a

CRC校验

CRC校验

二:手算CRC

手算的时候,最高项保留

写程序的时候,最高项不保留(优化执行次数)

CRC校验

三:代码分析

3.1、计算一个字节

//CRC-8
//计算单个字节
#include <iostream> //&#x652F;&#x6301;uint&#x7C7B;&#x578B;
uint8_t cal_table_high_first(uint8_t value)
{
    uint8_t crc;
    crc = value;
    /* &#x6570;&#x636E;&#x5F80;&#x5DE6;&#x79FB;&#x4E86;8&#x4F4D;&#xFF0C;&#x9700;&#x8981;&#x8BA1;&#x7B97;8&#x6B21; */
    for (int i =0 ; i< 8 ; i++)
    {
        //1000 0000 = 0x80
        //&#x5224;&#x65AD;&#x6700;&#x9AD8;&#x4F4D;&#x662F;&#x5426;&#x4E3A;1
        if (crc & 0x80)
        {
          //&#x5982;&#x679C;&#x4E3A;1&#xFF0C;&#x5148;&#x5DE6;&#x79FB;&#x4E00;&#x4F4D;&#x7136;&#x540E;&#x518D;&#x4E0E;&#x591A;&#x9879;&#x5F0F;x31&#x5F02;&#x6216;
          //0011 0001 = 0x31 x^8+x^5+x^4+1
          //&#x5DE6;&#x79FB;&#x4E00;&#x4F4D;&#x662F;&#x4E3A;&#x4E86;&#x7B80;&#x5316;&#x6700;&#x9AD8;&#x9879;x^8&#x7684;&#x8BA1;&#x7B97;
             crc = (crc << 1) ^ 0x31;        }
        else
        {
          //&#x5982;&#x679C;&#x4E3A;0&#xFF0C;&#x5219;&#x4E0D;&#x9700;&#x8981;&#x5F02;&#x6216;&#xFF0C;&#x6574;&#x4F53;&#x6570;&#x636E;&#x5DE6;&#x79FB;&#x4E00;&#x4F4D;
             crc = (crc << 1);
        }
    }
    return crc;
}
</iostream>

3.2、计算多个字节

//CRC-8
//&#x8BA1;&#x7B97;&#x591A;&#x4E2A;&#x5B57;&#x8282;
#include <iostream>  //&#x652F;&#x6301;uint&#x7C7B;&#x578B;
uint8_t crc_high_first(uint8_t  *ptr, int len)
{
    uint8_t crc=0x00&#xFF1B; /* &#x8BA1;&#x7B97;&#x7684;&#x521D;&#x59CB;crc&#x503C; */
    while(len--)
    {
        //&#x5148;&#x628A;&#x4E0A;&#x4E00;&#x5B57;&#x8282;&#x4E0E;&#x4E0B;&#x4E00;&#x5B57;&#x8282;&#x5F02;&#x6216;
        crc ^= *ptr++;
        //&#x4E0B;&#x9762;&#x7684;&#x4EE3;&#x7801;&#x4E0E;&#x8BA1;&#x7B97;&#x4E00;&#x4E2A;&#x5B57;&#x8282;&#x7684;&#x4E00;&#x81F4;
        for (int i=0; i<8 ; i++) { if (crc & 0x80) crc="(crc" << 1) ^ 0x31; else 1); } return (crc); < code></8></iostream>

3.3、产生表

//&#x751F;&#x6210;&#x8868;
//&#x8C03;&#x7528;&#x4E86;&#x4E0A;&#x65B9;&#x7684;&#x51FD;&#x6570;

#include <iostream>  //&#x652F;&#x6301;uint&#x7C7B;&#x578B;
#include <stdio.h>
void  create_crc_table(void)
{

        int i = 0x00;

        for (; i<=0xff; i++) { if (0="=" (i%16)) printf("\n"); 把每个字节的crc检验码的结果保存下来 printf("0x%.2x, ", cal_table_high_first (i)); } < code></=0xff;></stdio.h></iostream>

3.4、查表方式生成CRC

//&#x67E5;&#x8868;&#x8BA1;&#x7B97;CRC
#include <iostream>  //&#x652F;&#x6301;uint&#x7C7B;&#x578B;
uint8_t cal_crc_table(uint8_t *ptr, int len)
{
    //&#x521D;&#x59CB;&#x5316;
    uint8_t crc = 0x00;
    while (len--)
    {
        crc = crc_table[crc ^ *ptr++];
        //&#x7B49;&#x4EF7;&#x4E0E;  crc = crc_table[  crc ^ (*ptr) ];
        //         ptr++;
    }
    return crc;
}
</iostream>

3.5、反转

uint32_t ReflectedData(uint32_t data, REFLECTED_MODE mode)
{
    data = ((data & 0xffff0000) >> 16) | ((data & 0x0000ffff) << 16);
    data = ((data & 0xff00ff00) >> 8) | ((data & 0x00ff00ff) << 8);
    data = ((data & 0xf0f0f0f0) >> 4) | ((data & 0x0f0f0f0f) << 4);
    data = ((data & 0xcccccccc) >> 2) | ((data & 0x33333333) << 2);
    data = ((data & 0xaaaaaaaa) >> 1) | ((data & 0x55555555) << 1);

    switch (mode)
    {
    case REF_32BIT:
        return data;
    case REF_16BIT:
        return (data >> 16) & 0xffff;
    case REF_8BIT:
        return (data >> 24) & 0xff;
    case REF_7BIT:
        return (data >> 25) & 0x7f;
    case REF_6BIT:
        return (data >> 26) & 0x7f;
    case REF_5BIT:
        return (data >> 27) & 0x1f;
    case REF_4BIT:
        return (data >> 28) & 0x0f;
    }
    return 0;
}

Original: https://www.cnblogs.com/agui125/p/15942563.html
Author: 风御之举
Title: CRC校验

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/606504/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 消费税

    1994年税制改革时,我国才设置了独立的消费税,与实行普遍征收的增值税配套,对特定消费品进行特殊调节。 消费税的特点: (一)征税范围具有选择性 有选择地确定若干个征税项目,在税法…

    Linux 2023年6月14日
    0102
  • ADB和Fastboot最新版的谷歌官方下载链接

    最新ADB及Fastboot版本说明(SDK Platform Tools 版本说明) ADB和Fastboot for Windows ADB和Fastboot for Mac …

    Linux 2023年6月7日
    098
  • shell大全定时清空文件内容,定时记录文件大小

    shell大全定时清空文件内容,定时记录文件大小 bash;gutter:true;</p> <h1>!/bin/bash</h1> <h…

    Linux 2023年5月28日
    0120
  • 灵敏度分析简介

    参考文章1 😄参考文章2 😸参考文章3 😃 1. 灵敏度分析: 某一个假定的常量,在现实中不可能完全保持不变,可能发生一定范围的波动。灵敏度分析就是检验这部分波动对结果的影响。 灵…

    Linux 2023年6月14日
    094
  • shell 同时执行多任务下载视频

    本文为博主原创,转载请注明出处: shell 脚本不支持多线程,但我们需要用shell 脚本同时跑多个任务时怎么让这些任务并发同时进行,可以采用在每个任务 后面 添加一个 &amp…

    Linux 2023年5月28日
    0102
  • Git简介

    Git是一个开源的分布式版本控制系统,是目前主流的版本控制系统,很多软件项目都会用它做源代码管理。Git的常用操作想必很多人都会,但是可能了解Git内部原理的人并不多。了解一些底层…

    Linux 2023年6月6日
    074
  • [Git系列] Git 基本概念

    版本控制系统 版本控制系统是一种帮助软件开发人员实现团队协作和历史版本维护的软件。版本控制系统应具备以下基本功能: [En] Version control system is a…

    Linux 2023年5月27日
    094
  • VMware ESXi 7.0 U3 SLIC 2.6 & Unlocker

    提供标准版和 Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮)、Cisco (思科) 定制版镜像 请访问原文链接:VMware ESXi 7.0…

    Linux 2023年5月27日
    072
  • R语言-基础绘图

    一、R语言绘图系统 二、绘图函数 2.1 高水平绘图函数 plot() 绘制散点图等多种图形 hist() 直方图 boxplot() 箱线图 stripchart() 点图 ba…

    Linux 2023年6月8日
    061
  • Ubuntu下使用apt-get命令查询并安装指定版本的软件

    执行以下命令,查询软件所有的版本号 sudo apt-cache madison <package></package> 执行以下命令,安装指定版本的软件 …

    Linux 2023年6月6日
    0101
  • 使用GVT-g为KVM添加虚拟显卡渲染3D图形

    0x00 前言 可以在KVM虚拟机看电影、玩游戏哦。 我的环境如下: 0x01 启动GVT-g 要启用IOMMU、i915,编辑grub文件: $ sudo vim /etc/de…

    Linux 2023年5月27日
    0102
  • 记一次 namespace 卡在terminating

    Error from server (AlreadyExists): object is being deleted: namespaces “monitoring&#…

    Linux 2023年6月14日
    090
  • __pycache__

    最近在使用python写一个串口模块的时候,偶然发现运行脚本之后,在工程文件夹下面出现了这样一个文件夹__pycache__,所以就特意到网上查了一下这个文件夹是怎么回事。 &am…

    Linux 2023年6月14日
    0109
  • 剑指offer计划链表

    剑指offer计划链表 从尾到头打印链表 /** * public class ListNode { * int val; * ListNode next = null; * * …

    Linux 2023年6月11日
    069
  • 浅谈缓存击穿、缓存穿透、缓存雪崩、缓存预热、缓存降级

    对于缓存,大家肯定都不陌生,不管是前端还是服务端开发,缓存几乎都是必不可少的优化方式之一。在实际生产环境中,缓存的使用规范也是一直备受重视的,如果使用的不好,很容易就遇到缓存击穿、…

    Linux 2023年6月14日
    095
  • shell脚本中 /dev/null 的用途

    /dev/null 是一个特殊的设备文件,它丢弃一切写入其中的数据 可以将它 视为一个黑洞, 它等效于只写文件, 写入其中的所有内容都会消失, 尝试从中读取或输出不会有任何结果,同…

    Linux 2023年6月13日
    089
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球