ANSI CRC16校验算法的C#实现
首先,简述一下CRC16校验字节的生成步骤如下:
1) CRC16 校验寄存器赋值为0xFFFF;
2) 取被校验串的第一个字节赋值给临时寄存器;
3) 临时寄存器与CRC16 校验寄存器的高位字节进行“异或”运算,赋值给CRC16 校验寄存器;
4) 取CRC16 校验寄存器最后一位赋值给检测寄存器;
5) 把CRC16 校验寄存器右移一位;
6) 若检测寄存器值为1,CRC16 校验寄存器与多项式0xA001 进行“异或”运算,赋值给CRC16
校验寄存器;
7) 重复步骤4~6,直至移出8 位;
8) 取被校验串的下一个字节赋值给临时寄存器;
9) 重复步骤3~8,直至被校验串的所有字节均被校验;
10) 返回CRC16 校验寄存器的值。
校验码按照先高字节后低字节的顺序存放。
CRC 校验算法(C语言)示例:
1 /**************************************************************************************** 2 函 数: CRC16_Checkout 3 描 述: CRC16 循环冗余校验算法。 4 参 数 一: *puchMsg:需要校验的字符串指针 5 参 数 二: usDataLen:要校验的字符串长度 6 返 回 值: 返回CRC16 校验码 7 ****************************************************************************************/ 8 unsigned int CRC16_Checkout ( unsigned char *puchMsg, unsigned int usDataLen ) 9 { 10 unsigned int i,j,crc_reg,check; 11 crc_reg = 0xFFFF; 12 for(i=0;i<usDataLen;i++) 13 { 14 crc_reg = (crc_reg>>8) ^ puchMsg[i]; 15 for(j=0;j<8;j++) 16 { 17 check = crc_reg & 0x0001; 18 crc_reg >>= 1; 19 if(check==0x0001) 20 { 21 crc_reg ^= 0xA001; 22 } 23 } 24 } 25 return crc_reg; 26 }
示例:
##0101QN=20160801085857223;ST=32;CN=1062;PW=100000;MN=010000A8900016F000169DC0;Flag=5;CP=&&RtdInterval=30&&1C80\r\n,其中1C08 为CRC16 校验码,是对数据段QN=20160801085857223;ST=32;CN=1062;PW=100000;MN=010000A8900016F000169DC0;Flag=5;CP=&&RtdInterval=30&& 进行CRC16 校验所得的校验码。
C#源代码:
1 public static string CRC16(byte[] data) 2 { 3 ushort crc = 0xFFFF; 4 int len = data.Length; 5 for (int i = 0; i < len; i++) 6 { 7 crc = (ushort)((crc >> 8) ^ data[i]); 8 for (int j = 0; j < 8; j++) 9 crc = (crc & 1) == 1 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1); 10 } 11 return string.Format("{0:X}", crc).PadLeft(4, '0'); 12 }
调用示例:
1 string data = "QN=20200618135900000;ST=22;CN=2051;PW=123456;MN=XXXX0HZ0006018;CP=&&DataTime=20200618135900;a34001-Avg=0.106,a34001-Max=0.106,a34001-Min=0.106,a34001-Flag=N;a01001-Avg=57.8,a01001-Max=57.8,a01001-Min=57.8,a01001-Flag=N;a01002-Avg=49.4,a01002-Max=49.4,a01002-Min=49.4,a01002-Flag=N;a01006-Avg=100.12,a01006-Max=100.12,a01006-Min=100.12,a01006-Flag=N;a01007-Avg=1.3,a01007-Max=1.3,a01007-Min=1.3,a01007-Flag=N;a01008-Avg=82.0,a01008-Max=82.0,a01008-Min=82.0,a01008-Flag=N;a01001-Avg=142.6,a01001-Max=142.6,a01001-Min=142.6,a01001-Flag=N;&&"; 2 string crc = CRC16(System.Text.Encoding.UTF8.GetBytes(data));
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现