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博客发布新文章,敬…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
