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

news2024/11/15 12:29:20

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

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

不同应用规范通过对输入数据前处理和输出数据后处理的方式不同,又产生了不同的应用规范校验函数,这里介绍USB格式的CRC-16校验函数。USB格式对输入数据,预置值为0XFFFF(当做最初的余数),输入数据按照单个字节进行位反序。对于输出的校验码,进行整体位反序, 然后异或0xFFFF。

生成多项式为x^16 + x^15 + x^2 + 1

正向算法

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

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

#include <stdio.h>
#include <stdlib.h>
uint16_t PY_CRC_16_USB(uint8_t *di, uint32_t len)
{
    uint32_t crc_poly = 0x00018005;  //X^16+X^15+X^2+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] = 0;
		for(uint8_t m=0; m<=7; m++)
		{
			datain[j] |= ( ( di[j]>>(7-m) ) & 1 ) << m;
		}
	}
        datain[len] = 0; datain[len+1] = 0;//Compensate 16-bit '0' for input data

        datain[0] ^= 0xff; datain[1] ^= 0xff;

    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);

     uint16_t i_data_t = 0;

     for(uint8_t n=0; n<=15; n++)
     {
    	 i_data_t |=  ( ( data_t>>(15-n) ) & 1 ) << n;
     }

     return i_data_t ^ 0xFFFF;
}

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

uint16_t PY_CRC_16_S_USB(uint8_t *di, uint32_t len)
{
    uint16_t crc_poly = 0x8005;  //X^16+X^15+X^2+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] ;
	for(uint32_t j=0;j<len;j++)
	{
		cdata[j] = 0;

		for(uint8_t m=0; m<=7; m++)
		{
			cdata[j] |= ( ( di[j]>>(7-m) ) & 1 ) << m;
		}
	}
	cdata[len]=0; cdata[len+1]=0;

	cdata[0] ^= 0xff; cdata[1] ^= 0xff;

	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) ) ;
        }
    }

    uint16_t i_data_t = 0;

    for(uint8_t n=0; n<=15; n++)
    {
   	 i_data_t |=  ( ( data_t>>(15-n) ) & 1 ) << n;
    }

    return i_data_t ^ 0xFFFF;
}

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

uint16_t PY_CRC_16_T16_USB(uint16_t *di, uint32_t len)
{
	uint16_t crc_poly = 0x8005;  //X^16+X^15+X^2+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] = 0;
		for(uint8_t m=0; m<=7; m++)
		{
			cdata[j] |= ( ( ( (di[j]>>8)>>(7-m) ) & 1 ) << m ) | ( ( ( ( (di[j]&0x00ff)>>(7-m) ) & 1 ) << m ) <<8 );
		}

	}

	cdata[0] ^= 0xffff;

    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;
        }
    }

    uint16_t i_data_t = 0;

    for(uint8_t n=0; n<=15; n++)
    {
   	 i_data_t |=  ( ( data_t>>(15-n) ) & 1 ) << n;
    }

    return i_data_t ^ 0xFFFF;
}

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

uint16_t PY_CRC_16_T8_USB(uint8_t *di, uint32_t len)
{
	uint16_t crc_poly = 0x8005;  //X^16+X^15+X^2+1 total 16 effective bits without X^16. 
	uint16_t data_t = 0; //CRC register

	uint8_t cdata[len];
	for(uint32_t j=0;j<len;j++)
	{
		cdata[j] = 0;
		for(uint8_t m=0; m<=7; m++)
		{
			cdata[j] |= ( ( di[j]>>(7-m) ) & 1 ) << m;
		}
	}

	cdata[0] ^= 0xff; cdata[1] ^= 0xff;

    for(uint32_t i = 0; i < len; i++)
    {
    	data_t ^= cdata[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;

        }
    }

    uint16_t i_data_t = 0;

    for(uint8_t n=0; n<=15; n++)
    {
   	 i_data_t |=  ( ( data_t>>(15-n) ) & 1 ) << n;
    }

    return i_data_t ^ 0xFFFF;
}

反向算法

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

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

uint16_t PY_CRC_16_T8_USB_i(uint8_t *di, uint32_t len)
{
	uint16_t crc_poly = 0xA001; //Bit sequence inversion of 0x8005
	uint16_t data_t = 0xFFFF; //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 & 0x0001)
            	data_t = (data_t >> 1) ^ crc_poly;
            else
            	data_t >>= 1;
        }
    }

    return data_t ^ 0xFFFF;
}

算法验证

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

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

–End–

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

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

相关文章

计算机图形辐照度学、光度学

文章目录 前言&#xff1a;一、什么是辐照度学二、什么是光度学 前言&#xff1a; 在计算机图形学中是把辐射(Radiance)等概念和亮度(Luminance)等概念不做区分的。辐射是辐照度学的概念&#xff0c;而亮度则是光度学上的概念。 辐照强高度并不意味着亮度就强&#xff0c;就比如…

VTK 几何体连通区域分析 vtkPolyDataConnectivityFilter

前言&#xff1a; vtkPolyDataConnectivityFilter 使用过&#xff0c;但网上没有看到完事的教程&#xff1b;这里整理一下&#xff1b; 提取数据集中连通的多边形数据。 该类是一个滤波器&#xff0c;提取cell&#xff08;区域&#xff09; - 拥有公共点或者满足某个阈值 该类…

Soft-RoCE部署及通信测试

Soft-RoCE部署及通信测试 Soft-RoCE是一种基于软件的RoCE&#xff08;RDMA over Converged Ethernet&#xff09;实现。RoCE是一种在以太网上实现RDMA&#xff08;Remote Direct Memory Access&#xff09;的技术&#xff0c;它允许数据在网络中直接传输&#xff0c;而无需CPU…

【ElasticSearch】几点优化及面试相关

文章目录 硬件选择分片策略合理设置分片数推迟分片分配 路由选择写入速度优化(磁盘优化)批量数据提交优化存储设备合理使用合并减少 Refresh 的次数加大 Flush 设置减少副本的数量 内存设置ES配置文件解析Elasticsearch 面试题为什么要使用 Elasticsearch?Elasticsearch 的 ma…

【Java网络编程】基于UDP-Socket 实现客户端、服务器通信

​ 哈喽&#xff0c;大家好~我是你们的老朋友&#xff1a;保护小周ღ 本期为大家带来的是网络编程的 UDP Socket 套接字&#xff0c;基于 UDP协议的 Socket 实现客户端服务器通信&#xff0c;Socket 套接字可以理解为是&#xff0c;传输层给应用层提供的一组 API&#xff0c;…

Java中提升接口性能的一些方法

目录 1.使用线程池并行执行2.数据库优化2.1 小表关联大表2.2 反三大范式操作2.3 增加索引2.4 减小事务粒度2.5 读写分离、分库分表 3.拥抱缓存3.1 Redis3.2 内存缓存 4.锁和异步4.1 减小锁的粒度4.2 分布式锁 1.使用线程池并行执行 假如有一个接口的逻辑如下&#xff1a; 接口…

cadence遇到的问题

1、最烦人的&#xff0c;突然卡住。 设置grid卡住&#xff0c;导出libraries卡住&#xff0c;选择其他产品时卡住。 从微软拼音输入法改成美式键盘后能解决一些问题。但不能解决全部。 今天下载了搜狗输入法来替代微软自带输入法。效果奇佳&#xff0c;真的可以诶。 2、如果…

沁恒 CH32V208(一): CH32V208WBU6 评估板上手报告和Win10环境配置

目录 沁恒 CH32V208(一): CH32V208WBU6 评估板上手报告和Win10环境配置 CH32V208 CH32V208系列是沁恒32位RISC-V中比较新的一个系列, 基于青稞RISC-V4C内核, 最高144MHz主频, 64KB SRAM&#xff0c;128KB Flash, 供电电压2.5/3.3V. 这个型号的特点: 除了特有的硬件堆栈区、…

【C++11那些事儿(三)】

文章目录 一、可变参数模板1.1 概念引入1.2 递归函数方式展开参数包1.3 逗号表达式展开参数包1.4 可变参数模板在STL中的应用 二、包装器1.1 function1.2 bind 一、可变参数模板 1.1 概念引入 C11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板&#x…

链表的添加修改删除操作

public class HeroNodeDemo {public static void main(String[] args) {HeroNode hero1 new HeroNode(1, "松江");HeroNode hero2 new HeroNode(2, "武松");HeroNode hero3 new HeroNode(3, "及时雨");HeroNode hero4 new HeroNode(4, "…

AWVS-window版本安装

Acunetix Web Vulnerability Scanner&#xff08;简称AWVS&#xff09;是一款知名的网络漏洞扫描工具&#xff0c;它通过网络爬虫测试你的网站安全&#xff0c;检测流行安全漏洞。 一、下载 链接&#xff1a;https://pan.baidu.com/s/1GuLCmYBmhVYA2_qBwfjZhw 提取码&#x…

管家婆安装导致电脑蓝屏问题解决方案

安装完管家婆后&#xff0c;电脑蓝屏&#xff0c;重启还是蓝屏&#xff0c;这该怎么办&#xff1f; 导致的原因&#xff1a;因加密狗驱动不适配于Windows10系统&#xff0c;导致电脑蓝屏 修复方案&#xff1a;进入电脑安全模式&#xff08;怎么进入问度娘&#xff09;&#…

css奇淫巧计

1.input文本内容替换 -webkit-text-security&#xff1a;通过用形状替换字符,仅影响那些字段不是的typepassword 可选值:none &#xff08;无&#xff09;&#xff0c;circle &#xff08;圆圈&#xff09;&#xff0c;disc &#xff08;圆形&#xff09;&#xff0c;square &a…

【STM32CubeMX】串口通信

前言 本文记录下我学习STM32CubeMX时的流程&#xff0c;方便以后回忆。本章记录串口通信。这里居然有玄学问题&#xff0c;给我整了好久&#xff0c;头都大了。可能也是我能力有限才有的吧&#xff0c;泪目。 目录 串口通信 串口通信 STM32CubeMX中的串口配置&#xff0c;配…

MiniGPT-4引领潮流,GPT-4提前发布图片阅读功能

ChatGPT中国站翻译自medium.com 让我们来看看如何玩Minigpt-4并将其应用到日常生活中。 今年三月&#xff0c;OpenAI 宣布了 GPT-4 的图像识别功能&#xff0c;这意味着 GPT 技术又被提升一个维度。-4 尚未发布给大众使用很长时间&#xff0c;所以终于有人忍不住了&#xff01;…

由 ChatGPT 团队开发,堪称辅助神器!IntelliJ IDEA 神级插件

什么是Bito&#xff1f; 为什么要使用Bito&#xff1f; 如何安装Bito插件 如何使用Bito插件 什么是Bito&#xff1f; Bito是一款由ChatGPT团队开发的IntelliJ IDEA编辑器插件&#xff0c;旨在提高开发人员的工作效率。此插件强大之处在于它不仅可以帮助开发人员更快地提交…

vulnhub靶机sar

准备工作 下载连接&#xff1a;https://download.vulnhub.com/sar/sar.zip 下载完后解压&#xff0c;然后双击打开&#xff0c;VMware导入OVA 网络环境&#xff1a;DHCP、NAT 信息收集 主机发现 先扫描整个C段 192.168.100.132应该就是我们的目标 端口扫描 扫描目标主机…

3个经典线程同步问题

生产者消费者问题 问题描述 系统中有一组生产者进程和一组消费者进程&#xff0c;生产者进程每次生产一个产品放入缓冲区&#xff0c;消费者进程每次从缓冲区中取出一个产品并使用。生产者、消费者共享一个初始为空、大小为n的缓冲区 伪码描述 semaphore mutex 1;//互斥信…

Zabbix服务端监控目标主机的Web服务(网站的访问延迟)

zabbix服务端和目标主机的部署见上一篇文章&#xff1a; http://t.csdn.cn/XD5Hc Zabbix服务端监控目标主机 服务端启动zabbix服务后&#xff0c;在浏览器上访问&#xff1a;http&#xff1a;//IP/zabbix 1.创建主机群主&#xff08;名字自定义&#xff09; 2.创建主机 主…

javaEE基于SSh学生选课系统

设计内容1. 搜集相关资料、作出功能需求分析&#xff1b; 2. 各个功能模块的基本功能大体如下&#xff1a; (1). 管理员模块 包括个人中心、专业管理、班级管理、课程管理、教师管理、选课管理。&#xff0e; (2).教师模块 包括个人中心、课程信息、出勤管理、成绩管理。 (3)…