C语言CRC-16 XMODEM格式校验函数

C语言CRC-16 XMODEM格式校验函数

CRC-16校验产生2个字节长度的数据校验码,通过计算得到的校验码和获得的校验码比较,用于验证获得的数据的正确性。基本的CRC-16校验算法实现,参考: C语言标准CRC-16校验函数。

不同应用规范通过对输入数据前处理和输出数据后处理的方式不同,又产生了不同的应用规范校验函数,这里介绍XMODEM格式的CRC-16校验函数。实际上XMODEM符合标准CRC-16计算过程,并无前处理和后处理,仅需注意生成多项式即可。

生成多项式为x^16 + x^12 + x^5 + 1
由于反向算法更适合于有输入字节倒位序和输出整体数据倒位序的情况,这里只介绍正向算法。

正向算法

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

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

#include <stdio.h>
#include <stdlib.h>
uint16_t PY_CRC_16_XMODEM(uint8_t *di, uint32_t len)
{
	uint32_t crc_poly = 0x00011021;  //X^16+X^12+X^5+1 total 17 effective bits. Computed total data shall be compensated 16-bit '0' before CRC computing.

	uint8_t *datain;
	uint64_t cdata = 0; //Computed total data
    uint32_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+2)/6;
    uint32_t cr=(len+2)%6;

	uint32_t j;

	datain = malloc(len+2);
	for(j=0;j<len;j++)
	{
		datain[j] = di[j];
	}
        datain[len] = 0; datain[len+1] = 0;//Compensate 16-bit '0' for input data

    if(len<=6)   //Mount data for only one segment
     {
    	 for(j=0;j<=(len+1);j++)
    	 {
    		 cdata = (cdata<<8);
    		 cdata = cdata|datain[j];
    	 }
    	 cn = 1;
     }
    else
     {
    	 if(cr==0)
    	 {
    		 cr = 6;
    	 }
         else if(cr==1)
         {
             cr = 7;

         }
         else if(cr==2)
         {
             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-16));
 				{
 					data_t = data_t ^ crc_poly;
 				}

 	            while((index!=0x5555)&&(index!=0xaaaa))
 	            {

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

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

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

 	        			}

 	    			}

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

 		if(cn>0) //next segment
 		{
  			cdata = data_t&0x00ffff;

 			for(uint8_t k=0;k<6;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);

     free(datain);
     return (uint16_t)data_t;
}

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

uint16_t PY_CRC_16_S_XMODEM(uint8_t *di, uint32_t len)
{
	uint16_t crc_poly = 0x1021;  //X^16+X^12+X^5+1 total 16 effective bits without X^16. Computed total data shall be compensated 16-bit '0' before CRC computing.

	uint32_t clen = len+2;
	uint8_t cdata[clen] ;
	memcpy(cdata, di, len); cdata[len]=0; cdata[len+1]=0;
	uint16_t data_t = (((uint16_t)cdata[0]) << 8) + cdata[1]; //CRC register

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

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

uint16_t PY_CRC_16_T16_XMODEM(uint16_t *di, uint32_t len)
{
	uint16_t crc_poly = 0x1021;  //X^16+X^12+X^5+1 total 16 effective bits without X^16. 
	uint16_t data_t = 0; //CRC register

	uint16_t cdata[len];
	for(uint32_t j=0;j<len;j++)
	{
		cdata[j] = (di[j]>>8 | di[j]<<8);
	}

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

        for (uint8_t j = 0; j < 16; j++)
        {
            if (data_t & 0x8000)
            	data_t = (data_t << 1) ^ crc_poly;
            else
            	data_t <<= 1;
        }
    }
    return (data_t);
}

CRC-16 XMODEM格式校验函数四(8位输入数据格式):

uint16_t PY_CRC_16_T8_XMODEM(uint8_t *di, uint32_t len)
{
	uint16_t crc_poly = 0x1021;  //X^16+X^12+X^5+1 total 16 effective bits without X^16. 
	uint16_t data_t = 0; //CRC register

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

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

        }
    }
    return (data_t);
}

算法验证

4种算法结果相同:
在这里插入图片描述

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

–End–

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

三分钟阿里云服务器u1通用算力型性能、使用限制及费用说明

阿里云服务器u1是通用算力型云服务器&#xff0c;CPU采用2.5 GHz主频的Intel(R) Xeon(R) Platinum处理器&#xff0c;通用算力型u1云服务器不适用于游戏和高频交易等需要极致性能的应用场景及对业务性能一致性有强诉求的应用场景(比如业务HA场景主备机需要性能一致)&#xff0c…

C/C++每日一练(20230512) 成绩打印、补齐数组、水仙花数

目录 1. 成绩打印 ※ 2. 按要求补齐数组 &#x1f31f;&#x1f31f;&#x1f31f; 3. 水仙花数 ※ &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 成绩打印 一个班有10个同学&am…

隐语v0.8.2版本更新,首次发布TEEU

隐语v0.8.2版本更新&#x1f31f; 应用层 机器学习&#xff1a; - MPC 纵向 LR &#xff08;SSRegression&#xff09;新增 Policy SGD 优化器和 Early Stopping 支持&#xff0c;减少调参成本&#xff0c;加快收敛速度&#xff1b; - WOE 分箱进行了若干优化&#xff0c;性…

本地搭建wamp服务器并内网穿透实现无公网IP远程访问

文章目录 前言1.Wamp服务器搭建1.1 Wamp下载和安装1.2 Wamp网页测试 2. Cpolar内网穿透的安装和注册2.1 本地网页发布2.2 Cpolar云端设置2.3 Cpolar本地设置 3. 公网访问测试4. 结语 转载自cpolar极点云的文章&#xff1a;无公网IP&#xff1f;教你在外远程访问本地Wamp服务器「…

前端CSS学习(三)

1、盒子模型 盒子的概念1、页面中的每一个标签&#xff0c;都可看做是一 个“盒子” &#xff0c;通过盒子的视角更方便的进行布局2、浏览器在渲染 (显示)网页时&#xff0c;会将网页中的元素看做是一个个的矩形区域&#xff0c;我们也形象的称之为盒子CSS中规定每个盒子分别由…

Postman安装及入门接口测试使用步骤

前言 在软件测试行业中&#xff0c;作为一款比jemter更便捷更好用的软件测试工具&#xff0c;postman以其便捷灵活性首当其冲&#xff0c;成为当今测试行业领域使用较广泛的主流系统软件接口测试工具。今天Darren洋为大家讲解postman这款软件测试工具的下载安装及入门接口测试步…

Linux权限 - 概念与管理 | 文件权限的修改与转让 【详解】

目录 Linux权限 Linux权限的概念 Linux权限的基础操作 (1).实现用户账号的切换 (2).仅提升当前指令的权限 Linux权限管理 1、文件访问者的分类&#xff08;人&#xff09; 2、文件类型和访问权限&#xff08;事物属性&#xff09; 3、文件权限值的表示方法 4、文件访…

刷题刷题。

自然数拆分 利用step记录组合情况&#xff0c;只用sum不能判断组合情况 1.选择dfs原因&#xff1a;产生排列组合&#xff0c;和为7&#xff0c;step为8&#xff0c;其中7个空位&#xff0c;第8个step为输出&#xff1b; 参量的设置sum&#xff0c;step (进入下一层&#xff09;…

ThingsBoard教程(四十):规则节点解析 计算增量节点 Calculate delta

本篇文章介绍一个ThingsBoard 规则引擎中的一个节点,Calculate delta Calculate delta 计算增量 该节点可以在规则中获取上一次遥测的值,以此可以实现二次遥测的差。比如一个设备,一天上传一次数据,如果你要对比今天和昨天的数据,并将两者数据差保存到数据库,就能够使用…

Spring MVC

目录 什么是Spring MVC MVC定义 MVC和Spring MVC的关系 怎么学Spring MVC 创建Spring MVC项目 0.使用Spring Boot来创建Spring MVC项目 1.实现连接 2.获取参数 获取单个参数 获取多个参数 获取对象 后端参数重命名 获取JSON对象 从基础的URL中获取参数 上传文件Re…

1688获取商品api接口

作为一名技术爱好者&#xff0c;我们总会遇到各种各样的技术问题&#xff0c;需要寻找合适的技术解决方案。而在互联网时代&#xff0c;我们可以快速通过搜索引擎获取丰富的技术资源和解决方案。然而&#xff0c;在不同的技术分享中&#xff0c;我们常常会遇到质量参差不齐的文…

linux中查看某个文件夹下文件的个数和大小

一、统计某个目录的文件和子目录的大小 1、stat指令 stat命令 主要用于显示文件或文件系统的详细信息&#xff0c;该命令的语法格式如下&#xff1a; -f  不显示文件本身的信息&#xff0c;显示文件所在文件系统的信息-L  显示符号链接-t  简洁模式&#xff0c;只显示…

如何压缩pdf文件大小?四种方法随意选择

如何压缩pdf文件大小&#xff1f;PDF文件格式由于其跨平台性&#xff0c;易于浏览、打印和传输等特点&#xff0c;在现代社会中广泛应用于各个领域。然而&#xff0c;随着PDF文件越来越大&#xff0c;传输及存储所需的时间也会变得越来越长&#xff0c;从而降低了工作效率。在这…

如何用ChatGPT协助搭建品牌视觉体系(VI)?

该场景对应的关键词库&#xff08;18个&#xff09;&#xff1a; VI体系、品牌、目标市场、品牌DNA、人群特征、设计理念、标志设计、配色方案、字体选择、图形元素、价值观、形象、客户经理、需求、品牌定位、目标受众、主色调、辅助色 提问模板&#xff08;2个&#xff09;&…

进阶自定义类型——结构体,枚举,联合

本章重点&#xff1a; 1.结构体 1.1 结构体类型的声明 1.2 结构的自引用 1.3 结构体变量的定义和初始化 1.4 结构体内存对齐 1.5 结构体传参 1.6 结构体实现位段(位段的填充&可移植性) 2.枚举 2.1 枚举类型的定义 2.2 枚举的优点 2.3 枚举的使用 3.联合 3.1 联合类…

【TCP 协议】连接管理之 “三次握手,四次挥手”

哈喽&#xff0c;大家好~我是你们的老朋友&#xff1a;保护小周ღ 本期为大家带来的是网络编程中的 TCP 传输控制协议保证数据可靠性传输的机制之一的——连接管理&#xff0c;通信双方采用 “三次握手” 来建立连接&#xff0c;采用 “四次挥手” 会断开连接&#xff0c;如何…

React + ts学习笔记

前提准备&#xff1a; 环境配置 安装node.js 官网安装&#xff1a;当前使用版本18.15.0 安装新的react应用&#xff1a; 运行命令新建react-app npx create-react-app study-ts-app当前版本&#xff1a; “react”: “^18.2.0”,“react-dom”: “^18.2.0”, 如果出现如…

CompletableFuture使用教学

CompletableFuture使用教学 一、开始一个线程异步执行不需要返回值 通过runAsync方式 //1.不加线程池方式 CompletableFuture<Void> completableFuture CompletableFuture.runAsync(() -> {System.out.println(Thread.currentThread().getName());//停顿几秒try {…

对象应用:C++字符串和vector,对象的new与delete重构

对象应用 C字符串和vector字符串创建方式字符串拼接字符串追加 字符串截断autovector创建方式vector操作 new与delete重构new与delete的工作步骤new与delete重构应用只能生成栈对象只能生成堆对象 C字符串和vector C的字符串是一个对象&#xff0c;存在于std标准库中&#xff0…

[echarts] legend icon 自定义的几种方式

echarts 官方配置项 地址 一、默认 图例项的 icon circle, rect, roundRect, triangle, diamond, pin, arrow, none legend: {top: 5%,left: center,itemWidth: 20,itemHeight: 20,data: [{icon: circle, name: 搜索引擎},{icon: rect, name: 直接访问},{icon: roundRect, n…