CRC-16-modbus循环校验方法
该方法未修改前来自AI问答,可是结果是小端序列,ModbusRtu协议是大端序列,因为在输出处我修改成了大端序列输出,再强调一下,西门子PLC中的存储方式也是大端序列,即高字节在前,低字节在后,按照人们熟知的方式存储数据。
以下是一个用于 Modbus 中 CRC-16 循环校验的方法,包含校验验证功能,输出结果为字节数组形式:
代码块:
public static class Crc16Helper
{
private const ushort polynomial = 0xA001;
private static ushort[] crcTable = new ushort[256];
private void Crc16Helper()
{
for (int i = 0; i < 256; i++)
{
ushort crc = (ushort)i;
for (int j = 0; j < 8 j if crc 1='= 1)' crc='(ushort)((crc'>> 1) ^ polynomial);
}
else
{
crc >>= 1;
}
}
crcTable[i] = crc;
}
}
public static byte[] CalculateCrc(byte[] data) //CRC-16计算方法
{
ushort crc = 0xFFFF;
foreach (byte b in data)
{
crc = (ushort)((crc >> 8) ^ crcTable[(crc ^ b) & 0xFF]);
}
Byte[] result= new byte[] { (byte)(crc >> 8), (byte)crc };
// 将CRC转换为大端序
if (BitConverter.IsLittleEndian)
{
Array.Reverse(result); // 转换为大端序
}
return result;
}
public static bool VerifyCrc(byte[] data, byte[] receivedCrc)//验证校验结果是否正确
{
byte[] calculatedCrc = CalculateCrc(data);
return calculatedCrc[0] == receivedCrc[0] && calculatedCrc[1] == receivedCrc[1];
}
}
测试代码块:
static void Main()
{
byte[] data = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x02 };
// 计算CRC并输出为byte数组
byte[] crcBytes = Crc16Helper.CalculateCrc(data);
Console.WriteLine($"CRC: {crcBytes[0]},{crcBytes[1]}");
// 校验CRC
bool isValid = Crc16Helper.VerifyCrc(data, crcBytes);
Console.WriteLine($"CRC校验结果: {isValid}");
}
输出结果是:
CRC: 196,11
CRC校验结果: True