C语言CRC-8 ROHC格式校验函数

news2024/9/20 20:23:52

C语言CRC-8 ROHC格式校验函数

CRC校验基于前处理和后处理的不同,由不同的协会标准推出了一些不同格式的版本。这里介绍CRC-8 ROHC格式的校验函数。

CRC-8 ROHC格式特征

标准CRC-8的校验函数参考: C语言标准CRC-8校验函数
CRC-8 ROHC格式有如下的不同:

  1. 初始值预设为0xFF
  2. 输入数据的每个字节做反转,这里的反转不是指每个字节里的位反(取~),而每个字节里的位序反。也就是0x01需要反转为0x80。这里的反转是对每个字节单独进行反转,再形成新数组,不是对整个数组的所有位一起反转,所以0x01 0x02的反转是0x80 0x40而不是0x40 0x80。
  3. CRC计算完成得到的余数,还要做一次反转,仍然是位序反转,作为最后的输出结果
  4. 最后的结果要异或0x00,但任何字节数异或0x00等于其自身,故此条可省略。
  5. 计算的多项式为X^8 + X^2 + X^1 + 1

由上面的介绍可知,从标准CRC校验函数,调整几个方面的设计,就可形成CRC-8 MAXIM校验函数。

CRC-8 ROHC校验函数正向算法

正向算法是符合标准CRC-8的计算理论,从左向右计算,也即计算过程中移位时,向左移出。几种正向算法的实现如下:

CRC-8 ROHC格式校验函数一(8位输入数据格式,64位装载计算):

#include <stdio.h>
#include <stdlib.h>

uint8_t PY_CRC_8_ROHC(uint8_t *di, uint32_t len)
{
	uint16_t crc_poly = 0x0107; //X^8+X^2+X^1+1 total 9 effective bits. Computed total data shall be compensated 8-bit '0' before CRC computing.
	uint8_t *datain;
	uint64_t cdata = 0; //Computed total data
	uint16_t data_t = 0; //Process data of CRC computing

	uint16_t index_t = 63;  ///bit shifting index for initial '1' searching
	uint16_t index = 63;    //bit shifting index for CRC computing
	uint8_t rec = 0; //bit number needed to be compensated for next CRC computing

	uint32_t cn=(len+1)/7;
	uint32_t cr=(len+1)%7;

	uint32_t j;

	datain = malloc(len+1);
	for(j=0;j<len;j++)  //bit sequence inversion for input bytes
	{
		datain[j]=0;
		for(uint32_t m=0; m<8; m++)
		{
			datain[j] <<= 1;
			datain[j] |= ((di[j]>>m)&0x01);
		}
	}
	    datain[len]=0; //Compensate 8-bit '0' for input data
	    datain[0] ^= 0xff;

     if(len<=7)
     {
    	 for(j=0;j<=len;j++)
    	 {
    		 cdata = (cdata<<8);
    		 cdata = cdata|datain[j];
    	 }
    	 cn = 1;
     }
     else
     {
    	 if(cr==0)
    	 {
    		 cr=7;
    	 }
    	 if(cr==1)
    	 {
    		 cr=8;
    	 }
    	 else
    	 {
    		 cn++;
    	 }

    	 for(j=0;j<cr;j++)
    	 {
    		 cdata = (cdata<<8);
    		 cdata = cdata|datain[j];
    	 }
     }

     do
     {
 		cn--;

 		while(index_t>0)
 		{
 			if( (cdata>>index_t)&1 )
 			{
 				index = index_t;
 				index_t = 0;

 				data_t |= (cdata>>(index-8));
 				{
 					data_t = data_t ^ crc_poly;
 				}

 	            while((index!=0x5555)&&(index!=0xaaaa))
 	            {
 	            	/*
 	    			if ((data_t>>7)&1) rec = 1;
 	    			else if ((data_t>>6)&1) rec = 2;
 	    			else if ((data_t>>5)&1) rec = 3;
 	    			else if ((data_t>>4)&1) rec = 4;
 	    			else if ((data_t>>3)&1) rec = 5;
 	    			else if ((data_t>>2)&1) rec = 6;
 	    			else if ((data_t>>1)&1) rec = 7;
 	    			else if ((data_t>>0)&1) rec = 8;
 	    			else rec = 9; */

	 	    		for(uint8_t n=1;n<9;n++)
	 	    		{
	 	    			if ((data_t>>(8-n))&1) {rec = n;break;}
	 	    			if (n==8) rec=9;
	 	    		}

 	    			if((index-8)<rec)
 	    			{
 	    				data_t = data_t<<(index-8);
 	    				data_t |=  (uint16_t)((cdata<<(64-(index-8)))>>(64-(index-8)));
 	    				index = 0x5555;
 	    			}
 	    			else
 	    			{
 	        			for(uint8_t i=1;i<=rec;i++)
 	        			{
 	        				data_t = (data_t<<1)|((cdata>>(index-8-i))&1) ;
 	        			}

 	        			if(rec!= 9)
 	        			{
 	        				data_t = data_t ^ crc_poly;
 	        				index -= rec;
 	        			}
 	        			else
 	        			{
 	        				data_t = 0;
 	        				index_t = index-8-1;
 	        				index = 0xaaaa;

 	        			}

 	    			}

 	            }
 				if(index==0x5555) break;
 			}
 			else
 			{
 				index_t--;
 				if(index_t<8) break;
 			}
         }

 		if(cn>0)
 		{
  			cdata = data_t&0x00ff;

 			for(uint8_t k=0;k<7;k++)
 			{
 	    		 cdata = (cdata<<8);
 	    		 cdata = cdata|datain[j++];

 			}

 	    	data_t = 0;
 	 		index_t = 63;  ///bit shifting index for initial '1' searching
 	 		index = 63;    //bit shifting index for CRC computing
 	 		rec = 0; //bit number needed to be compensated for next CRC computing
 		}

     }
     while(cn>0);

     //bit sequence inversion for output byte
     datain[0] = data_t;
     data_t = 0;
	 for(uint32_t m=0; m<8; m++)
	{
		data_t <<= 1;
		data_t |= ((datain[0]>>m)&0x01);
	}

     free(datain);
     return data_t;

}

CRC-8 ROHC格式校验函数二(8位输入数据格式):

#include <stdio.h>
#include <stdlib.h>
uint8_t PY_CRC_8_S_ROHC(uint8_t *di, uint32_t len)
{
	uint8_t crc_poly = 0x07; //X^8+X^2+X^1+1 total 8 effective bits without X^8. Computed total data shall be compensated 8-bit '0' before CRC computing.

	uint32_t clen = len+1;
	uint8_t cdata[clen] ;

	for(uint32_t j=0;j<len;j++)  //bit sequence inversion for input bytes
	{
		cdata[j]=0;
		for(uint32_t m=0; m<8; m++)
		{
			cdata[j] <<= 1;
			cdata[j] |= ((di[j]>>m)&0x01);
		}
	}
	cdata[len]=0; //Compensate 8-bit '0' for input data

	uint8_t data_t = cdata[0] ^ 0xff; //CRC register

    for (uint32_t i = 1; i < clen; i++)
    {
        for (uint8_t j = 0; j <= 7; j++)
        {
            if(data_t&0x80)
            	data_t = ( (data_t<<1) | ( (cdata[i]>>(7-j))&0x01) ) ^ crc_poly;
            else
            	data_t = ( (data_t<<1) | ( (cdata[i]>>(7-j))&0x01) ) ;
        }
    }

    //bit sequence inversion for output byte
    cdata[0] = data_t;
    data_t = 0;
	 for(uint32_t m=0; m<8; m++)
	{
		data_t <<= 1;
		data_t |= ((cdata[0]>>m)&0x01);
	}
    return data_t;
}

CRC-8 ROHC格式校验函数三(8位输入数据格式):

uint8_t PY_CRC_8_T_ROHC(uint8_t *di, uint32_t len)
{
	uint8_t crc_poly = 0x07; //X^8+X^2+X^1+1 total 8 effective bits without X^8.
	uint32_t clen = len+1;
	uint8_t cdata[clen] ;

	for(uint32_t j=0;j<len;j++)  //bit sequence inversion for input bytes
	{
		cdata[j]=0;
		for(uint32_t m=0; m<8; m++)
		{
			cdata[j] <<= 1;
			cdata[j] |= ((di[j]>>m)&0x01);
		}
	}
	cdata[len]=0; //Compensate 8-bit '0' for input data

	uint8_t data_t = 0xff; //CRC register

    for (uint32_t i = 0; i < len; i++)
    {
    	data_t ^=  cdata[i];
        for (int8_t i=8; i>0; --i)
        {
            if (data_t & 0x80)
            	data_t = (data_t<<1) ^ crc_poly;
            else
            	data_t = (data_t<<1);
        }
    }

    //bit sequence inversion for output byte
    cdata[0] = data_t;
    data_t = 0;
	 for(uint32_t m=0; m<8; m++)
	{
		data_t <<= 1;
		data_t |= ((cdata[0]>>m)&0x01);
	}
    return data_t;
}

反向算法

反向算法是从由右向左计算,也即计算过程中移位时,向右移出。而计算过程中的输入数据高优先计算位和校验参数的对齐关系不变。因此把一个字节放在CRC计算寄存器的最低字节时,对于ROHC格式,最右侧最低位实际上是高优先计算位,而校验参数要相应倒序,从而计算位置对照关系不变。

CRC-8 ROHC格式校验函数四(反向算法,8位输入数据格式):

uint8_t PY_CRC_8_T_ROHC_i(uint8_t *di, uint32_t len)
{
	uint8_t crc_poly = 0xE0; //Bit sequence inversion of 0x07
	uint8_t data_t = 0xff; //CRC register

    for(uint32_t i = 0; i < len; i++)
    {
    	data_t ^= di[i]; //8-bit data

        for (uint8_t j = 0; j < 8; j++)
        {
            if (data_t & 0x01)
            	data_t = (data_t >> 1) ^ crc_poly;
            else
            	data_t >>= 1;
        }
    }

    return data_t;
}

可见对于CRC-8 ROHC格式校验函数,反向算法最简洁。

算法验证

4种算法结果相同:

在这里插入图片描述

通过在线CRC工具对照验证成功:
在这里插入图片描述

–End–

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

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

相关文章

Numpy从入门到精通——详解广播机制

这个专栏名为《Numpy从入门到精通》&#xff0c;顾名思义&#xff0c;是记录自己学习numpy的学习过程&#xff0c;也方便自己之后复盘&#xff01;为深度学习的进一步学习奠定基础&#xff01;希望能给大家带来帮助&#xff0c;爱睡觉的咋祝您生活愉快&#xff01; 这一篇介绍《…

机器学习-线性模型(波士顿房价预测)

机器学习-线性模型(波士顿房价预测) 文章目录 机器学习-线性模型(波士顿房价预测)人工智能、机器学习、深度学习的关系机器学习深度学习 波士顿房价预测数据集介绍模型假设 → \rightarrow →线性回归模型评价函数 → \rightarrow →均方误差线性回归模型网络结构实现波士顿房价…

HummerRisk V1.0 安装部署指南

HummerRisk v1.0 开始采用 springcloud 微服务架构&#xff0c;微服务架构更加易于扩展、易于容错、灵活部署&#xff0c;但是需要注意的是 HummerRisk v0.x 版本无法直接升级到 v1.0&#xff0c;如需使用 HummerRisk 请手动安装最新版本。 环境要求 全新安装的 Linux(x64)需要…

HashMap详解

手撕HashMap源码 HashMap一直是面试的重点。今天我们来了解了解它的源码吧&#xff01; 首先看一下Map的继承结构图 源码分析 什么是哈希 **Hash&#xff0c;一般翻译做“散列”&#xff0c;也有直接音译为“哈希”的&#xff0c;就是把任意长度的输入&#xff0c;通过散列算…

【Python语法系列】第三章:Python判断语句

进行逻辑判断&#xff0c;是生活中常见的行为。同样&#xff0c;在程序中&#xff0c;进行逻辑判断也是最为基础的功能&#xff0c;一个逻辑判断的流程非常简单&#xff0c;我们有一个判断的条件&#xff0c;那么他无非给我们返回两个结果&#xff0c;是或者否&#xff0c;是的…

Ubuntu22.04部署Pytorch2.0深度学习环境

文章目录 安装Anaconda创建新环境安装Pytorch2.0安装VS CodeUbuntu下实时查看GPU状态的方法小实验&#xff1a;Ubuntu、Windows10下GPU训练速度对比 Ubuntu安装完显卡驱动、CUDA和cudnn后&#xff0c;下面部署深度学习环境。 &#xff08;安装Ubuntu系统、显卡驱动、CUDA和cudn…

成本降低33%!英飞凌挑战智能汽车「高功率密度」瓶颈

伴随着汽车电动化、智能化的逐步推进&#xff0c;功率半导体器件的需求激增。其中&#xff0c;MOSFET作为新能源汽车中DC-DC、OBC等电源系统的重要组成部分&#xff0c;应用于汽车动力域以完成电能的转换与传输。同时&#xff0c;MOSFET还是可以用于ADAS、安全、信息娱乐等功能…

华为流程体系:MPP流程

今天主要来讲讲IPD中营销侧的另一个流程&#xff1a;MPP 流程。 在讲解MTL流程时&#xff0c;提到过MTL流程的底层逻辑是4C营销理论。 换句话说就是&#xff0c;MTL 流程是面向客户的产品上市流程。 而MPP流程则是面向产品的上市流程&#xff0c;它的底层逻辑就是经典的4P营…

新工具、新升级,推陈出新的测试好帮手

前言 【推陈出新】才是我们搞IT的正确发展方向&#xff0c;我们要以发展的眼光来看待我们使用的测试工具&#xff0c;如何升级您手中的测试工具&#xff0c;我们来品一品Eoink的Apikit五个维度对比我们之前用的测试工具&#xff1f; 我会按照&#xff1a;基础功能全面与否、大型…

Golang每日一练(leetDay0048) 链表专题

目录 141. 环形链表 Linked List Cycle &#x1f31f; 142. 环形链表 II Linked List Cycle II &#x1f31f;&#x1f31f; 143. 重排链表 Reorder List &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一…

全光谱防蓝光护眼灯有用吗?怎么分辨是全光谱灯

每个人的家里都有一两个台灯&#xff0c;孩子用来学习&#xff0c;老人用来阅读。但台灯不仅仅是用来照明而已&#xff0c;还需要呵护我们的双眼。现在的孩子患近视的人越来越多&#xff0c;很多小学生都戴上了眼镜&#xff0c;而老年人老花眼白内障的患者也在攀升&#xff0c;…

华三(H3C)GRE OVER IPsec实验

实验拓扑 目录 实验需求 1. 某企业北京总部、上海分支、武汉分支分别通过 R1&#xff0c;R3&#xff0c;R4 接入互联网&#xff0c;配置默认路由连通公网 2. 按照图示配置 IP 地址&#xff0c;R1&#xff0c;R3&#xff0c;R4 分别配置 Loopback0 口匹配感兴趣流&#xff0…

电子行业数字工厂管理系统有哪些优点和不足

随着制造业的不断发展&#xff0c;其生产技术也在不断改进&#xff0c;有许多电子企业都在部署数字工厂管理系统&#xff0c;进行数字化转型。如果不了解数字工厂管理系统&#xff0c;盲目部署的话&#xff0c;容易走很多弯路。本文将跟大家探讨一下&#xff0c;电子行业数字工…

本地Linux服务器安装宝塔面板,并公网远程登录

文章目录 前言1. 安装宝塔2. 安装cpolar内网穿透3. 远程访问宝塔4. 固定http地址5. 配置二级子域名6. 测试访问二级子域名 前言 宝塔面板作为建站运维工具&#xff0c;它支持一键LAMP/LNMP/集群/监控/网站/FTP/数据库/JAVA等100多项服务器管理功能&#xff0c;可提高运维效率。…

云原生|Packer插件开发在项目中应用

作者&#xff1a;李冠军 神州数码云基地 高级后端开发工程师 云时代我们可以在各云厂商控制台点一点&#xff0c;实例就生成了&#xff0c;但是这个点还是需要自己去点&#xff0c;如果把这些动作写成代码&#xff0c;直接运行&#xff0c;一切就完成了。 这就是Packer的作用…

使用Markdown编辑器

使用Markdown编辑器 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个注…

总结833

学习目标&#xff1a; 4月&#xff08;复习完高数18讲内容&#xff0c;背诵21篇短文&#xff0c;熟词僻义300词基础词&#xff09; 学习内容&#xff1a; 暴力英语&#xff1a;背《美丽心灵》&#xff0c;背《大独裁者》五六段&#xff0c;六百四十字的文章&#xff0c;明天加…

Java中的序列化与反序列化

序列化和反序列化作为 Java 里一个较为基础的知识点&#xff0c;但我相信很多人能了解的也就是那么几句而已&#xff0c;甚至都不了解&#xff0c;如果再深究问一下 Java 如何实现序列化和反序列化的&#xff0c;就可能不知所措了&#xff01; 不知道怎么说好&#xff0c;什么是…

GD(兆易创新)系列FLASH进行FPGA和ZYNQ配置固化相关操作

写在前面 本文主要针对使用GD&#xff08;兆易创新&#xff09;系列的FLASH做启动配置片时&#xff0c;遇到的相关问题进行简单整理复盘&#xff0c;避免后人踩坑。 本人操作固化芯片型号为&#xff1a;ZYNQ7045、690T&#xff08;复旦微替代型号V7 690T&#xff09;。 7系列…

为类创建事务码,读取EXCEL并显示报表简单版

屏幕以及字段定义 DATA: go_container TYPE REF TO cl_gui_custom_container. DATA: lv_subrc TYPE i,gv_action TYPE int4,lt_filetab TYPE filetable,ls_filetab TYPE file_table.DATA: gv_exit TYPE flag . DATA: lt_input TYPE TABLE OF alsmex_tabline,…