php实现 crc16 xmode校验,基于Modbus三种CRC16校验方法的性能对比

[toc]

#1.背景介绍 主要应用场景在物联网中,底端设备注册报文的上报,需要对报文的有效载荷(data)进行CRC16的复验,验证与设备端的CRC校验是否相等,如果相等,报文有效,设备上报就会注册成功,不是第一次则会刷新心跳时间,避免通信中断告警。设备的报文结果以及设备的CRC16位置如下:

b939ed0653914ab4e51a73d1c9c8598c.png

平台端需要重新对注册包内容(不包含设备的CRC计算字节)进行CRC校验计算,与设备端的CRC校验对比。如果相等,则平台端的CRC校验成功。

备注:本文的CRC校验全部指CRC16的校验。 #2. CRC校验的三种方法 本文侧重测试CRC的性能,不讲CRC校验的原理,因为CRC只是个校验数据准确性的工具,而且每个报文(不单单心跳报文),还有AI,DI,DO,AO,告警报文等都需要校验,因此,执行CRC程序段的性能显得尤为重要。 如果读者对CRC的校验原理感兴趣,请自行网上搜索相关资料进行深入研究,此处不再展开。 ##2.1. 直接计算CRC校验 以下代码已经做过验证,与设备端的CRC校验码相等(协议是基于变种的私有modbus协议),具体校验步骤可参考如下程序注释。最终将此类封装在了Crc16的帮助类里面。

///

/// 计算CRC16校验码

///

/// 校验数据

/// 多项式码

/// 校验码初始值

///

public static byte[] GetCRC16(byte[] value, ushort poly = 0xA001, ushort crcInit = 0xFFFF)

{

if (value == null || !value.Any())

throw new ArgumentException("生成CRC16的入参有误");

//运算

ushort crc = crcInit;

for (int i = 0; i < value.Length-2; i++)

{

//Step1.与校验对象的某字节取异或

crc = (ushort)(crc ^ (value[i]));

for (int j = 0; j < 8; j++)

{ //Step2.==0?右移1比特,否则右移1 bit与多项式异或

crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1);

}

}

byte hi = (byte)((crc & 0xFF00) >> 8); //高位置

byte lo = (byte)(crc & 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值