C语言CRC-16 IBM格式校验函数
C语言CRC-16 IBM格式校验函数
CRC-16校验产生2个字节长度的数据校验码,通过计算得到的校验码和获得的校验码比较,用于验证获得的数据的正确性。基本的CRC-16校验算法实现,参考: C语言标准CRC-16校验函数。
不同厂家通过对输入数据前处理和输出数据后处理的方式不同,又产生了不同的厂家校验函数,这里介绍IBM格式的CRC-16校验函数。IBM格式对输入数据,按照单个字节进行位反序。对于输出的校验码,进行整体位反序。
正向算法
正向算法是符合标准CRC-16的计算理论,从左向右计算,也即计算过程中移位时,向左移出。几种正向算法的实现如下:
CRC-16 IBM格式校验函数一(8位输入数据格式,64位装载计算):
#include <stdio.h>
#include <stdlib.h>
uint16_t PY_CRC_16_IBM(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 datauint32_t data_t = 0; //Process data of CRC computinguint16_t index_t = 63; ///bit shifting index for initial '1' searchinguint16_t index = 63; //bit shifting index for CRC computinguint8_t rec = 0; //bit number needed to be compensated for next CRC computinguint32_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 dataif(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' searchingindex = 63; //bit shifting index for CRC computingrec = 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;
}
CRC-16 IBM格式校验函数二(8位输入数据格式):
uint16_t PY_CRC_16_S_IBM(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;uint16_t data_t = (((uint16_t)cdata[0]) << 8) + cdata[1]; //CRC registerfor (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;elsedata_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;
}
CRC-16 IBM格式校验函数三(16位输入数据格式):
uint16_t PY_CRC_16_T16_IBM(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. Computed total data shall be compensated 16-bit '0' before CRC computing.uint16_t data_t = 0; //CRC registeruint16_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 );}}for(uint32_t i = 0; i < len; i++){data_t ^= cdata[i]; //16-bit datafor (uint8_t j = 0; j < 16; j++){if (data_t & 0x8000)data_t = (data_t << 1) ^ crc_poly;elsedata_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;
}
CRC-16 IBM格式校验函数四(8位输入数据格式):
uint16_t PY_CRC_16_T8_IBM(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.uint16_t data_t = 0; //CRC registeruint8_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;}}for(uint32_t i = 0; i < len; i++){data_t ^= cdata[i]<<8; //8-bit datafor (uint8_t j = 0; j < 8; j++){if (data_t & 0x8000)data_t = (data_t << 1) ^ crc_poly;elsedata_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;
}
反向算法
反向算法是从由右向左计算,也即计算过程中移位时,向右移出。而计算过程中的输入数据高优先计算位和校验参数的对齐关系不变。因此把一个字节放在CRC计算寄存器的最低字节时,对于IBM格式,最右侧最低位实际上是高优先计算位,而校验参数要相应倒序,从而计算位置对照关系不变。
CRC-16 IBM格式校验函数五(反向算法,8位输入数据格式):
uint16_t PY_CRC_16_T8_IBM_i(uint8_t *di, uint32_t len)
{uint16_t crc_poly = 0xA001; //Bit sequence inversion of 0x8005uint16_t data_t = 0; //CRC registerfor(uint32_t i = 0; i < len; i++){data_t ^= di[i]; //8-bit datafor (uint8_t j = 0; j < 8; j++){if (data_t & 0x0001)data_t = (data_t >> 1) ^ crc_poly;elsedata_t >>= 1;}}return data_t;
}
算法验证
5种算法结果相同:
通过在线CRC工具对照验证成功:
–End–
相关文章:

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

Maven高级-聚合和继承
Maven高级-聚合和继承3,聚合和继承3.1 聚合步骤1:创建一个空的maven项目步骤2:将项目的打包方式改为pom步骤3:pom.xml添加所要管理的项目步骤4:使用聚合统一管理项目3.2 继承步骤1:创建一个空的Maven项目并将其打包方式设置为pom步骤2:在子项目中设置其父工程步骤3:…...

如何写出10万+ Facebook 贴文?
想要创作一篇优秀的Facebook贴文,首先要考虑以下几个问题: 1.文案特点 一篇清晰简洁的文案有助于受众在有限的浏览时间内快速了解你想要展示的信息。根据以往经验,文案内容最好保持在20个汉字以内,加上链接描述最好也不要超过50…...

图像处理数据集
BSDS500 Berkeley Segmentation Dataset 500 是第一个用于评估超像素算法的数据集。对于参数优化,使用了验证集。 500张数据集200训练集train100验证集val200测试集test 每张图像有 5 个不同的高质量地面真值分割(groundTruth,是.mat文件) …...

文本聚类与摘要,让AI帮你做个总结
你好,我是徐文浩。 上一讲里,我们用上了最新的ChatGPT的API,注册好了HuggingFace的账号,也把我们的聊天机器人部署了出去。希望通过这个过程,你对实际的应用开发过程已经有了充足的体验。那么这一讲里,我们…...

leaflet实现波动的marker效果(131)
第131个 点击查看专栏目录 本示例的目的是介绍如何在vue+leaflet中显示波动的marker效果。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共76行)安装插件相关API参考:专栏目标示例效果 配置方式 1)查看基础设置…...
关于Dataset和DataLoader的概念
关于Dataset和DataLoader的概念 在机器学习中,Dataset和DataLoader是两个很重要的概念,它们通常用于训练和测试模型时的数据处理。 Dataset是指用于存储和管理数据的类。在深度学习中,通常将数据存储在Dataset中,并使用Dataset提…...
前端与JS变量
前端开发是当今互联网发展的重要组成部分,而JavaScript变量则是前端开发中不可或缺的一部分。在前端开发中,变量的作用不仅仅是存储数据,还可以用来控制程序流程、实现动态效果等。因此,学习前端与JavaScript变量是非常必要的。 …...

初始SpringBoot
初始SpringBoot1. SpringBoot创建和运行1.1. SpringBoot的概念1.2. SpringBoot的优点1.3. SpringBoot的创建1.3.0. 前置工作:安装插件(这是社区版需要做的工作, 专业版可以忽略)1.3.1. 社区版创建方式1.3.2. 专业版创建方式1.3.3. 网页版创建方式1.4. 项目目录介绍1.5. SpringB…...

vue+springboot 上传文件、图片、视频,回显到前端。
效果图 预览: 视频: 设计逻辑 数据库表 前端vue html <div class"right-pannel"><div class"data-box"><!--上传的作业--><div style"display: block" id""><div class"tit…...
java入门-W3(K81-K143)
一. 什么是对象 什么是对象?之前我们讲过,对象就是计算机中的虚拟物体。例如 System.out,System.in 等等。然而,要开发自己的应用程序,只有这些现成的对象还远远不够。需要我们自己来创建新的对象。 例如,…...
English Learning - L2 语音作业打卡 复习元音 [ɜː] [æ] 辅元连读技巧 Day42 2023.4.3 周一
English Learning - L2 语音作业打卡 复习元音 [ɜː] [] 辅元连读技巧 Day42 2023.4.3 周一💌发音小贴士:💌当日目标音发音规则/技巧:中元音 [ɜː]前元音 []辅元连读技巧🍭 Part 1【热身练习】🍭 Part2【练习内容】&…...
Thinkphp 6.0图像处理功能
本节课我们来学习一下图像处理功能,这功能是外置的,并非系统内置。 一.图像处理功能 1. 图像处理功能不是系统内置的功能了,需要通过 composer 引入进来; composer require topthink/think-image 2. 引入进来之后&…...

表格软件界的卷王,Excel、access、foxpro全靠边,WPS:真荣幸
Excel和Access就是表格软件的选择? 现在,铺天盖地的Excel的技能教程可谓是满天飞,有网上的教程,也有视频直播课程。 很多办公人员用Excel这种表格软件与VBA结合,甚至用不遗余力去学习Python编程语法,但Exce…...

Node.js -- http模块
1. 什么是http模块 在网络节点中,负责消费资源的电脑,叫客户端;负责对外提供网络资源的电脑,叫做服务器。 http模块是Node.js官方提供的,用来创建web服务器的模块。通过http模块提供的http.createServer()方法&#…...

静态库与动态库
库是已经写好的、成熟的、可复用的代码。在我们的开发的应用中经常有一些公共代码是需要反复使用的,就把这些代码编译为库文件。库可以简单看成一组目标文件的集合,将这些目标文件经过压缩打包之后形成的一个可执行代码的二进制文件。库有两种࿱…...
问题 A: C语言11.1
题目描述: 完成一个对候选人得票的统计程序。假设有3个候选人,名字分别为Li,Zhang和Fun。使用结构体存储每一个候选人的名字和得票数。记录每一张选票的得票人名,输出每个候选人最终的得票数。结构体可以定义成如下的格式&#x…...

SLAM中后端优化的技术细节总结与回答
SLAM中后端优化的技术细节 本文档主要收集总结了一些SLAM大佬们讲解后端优化中偏理论的技术细节的博客和回答以及一些学习教材。 Written by wincent 位姿估计以及李群相关的概述 Lie theory is by no means simple ———— 谎言理论绝不简单doge 《A micro Lie theory for st…...
小白快速学习Markdown
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…...

ToBeWritten之物联网WI-FI协议
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...