Modbus CRC 16 (C#)

算法

1.预置一个值为 0xFFFF 的 16 位寄存器,此寄存器为 CRC 寄存器。
2.把第 1 个 8 位二进制数据(即通信消息帧的第 1 个字节)与 16 位的 CRC 寄存器相异或,异或的结果仍存放在该 CRC 寄存器中。
3.把 CRC 寄存器的内容右移一位,用 0 填补最高位,并检测移出位是 0 还是 1.
4.如果移出位为0 ,则重复步骤(3)(再次右移一位);如果移出位为 1,则 CRC 寄存器与 0xA001 (多项式码)进行异或。
5.重复步骤(3)和(4),直到右移 8 次,这样整个 8 位数据全部进行了处理。
6.重复步骤(2)~(5),进行消息帧下一个字节的处理。
7.将该通信消息帧所有字节按上述步骤计算完成后,得到的 16 位 CRC 寄存器的高、低位进行交换。即发送时首先添加低位字节,然后添加高位字节。
8.最后得到的 CRC 寄存器内容即为CRC 校验码。

代码

public static byte[] GetModbusCrc16(byte[] bytes)
{
	byte crcRegister_H = 0xFF, crcRegister_L = 0xFF;// 预置一个值为 0xFFFF 的 16 位寄存器

	byte polynomialCode_H = 0xA0, polynomialCode_L = 0x01;// 多项式码 0xA001

	for (int i = 0; i < bytes.Length; i++)
	{
		crcRegister_L = (byte)(crcRegister_L ^ bytes[i]);

		for (int j = 0; j < 8; j++)
		{
			byte tempCRC_H = crcRegister_H;
			byte tempCRC_L = crcRegister_L;

			crcRegister_H = (byte)(crcRegister_H >> 1);
			crcRegister_L = (byte)(crcRegister_L >> 1);
			// 高位右移前最后 1 位应该是低位右移后的第 1 位:如果高位最后一位为 1 则低位右移后前面补 1
			if ((tempCRC_H & 0x01) == 0x01)
			{
				crcRegister_L = (byte)(crcRegister_L | 0x80);
			}

			if ((tempCRC_L & 0x01) == 0x01)
			{
				crcRegister_H = (byte)(crcRegister_H ^ polynomialCode_H);
				crcRegister_L = (byte)(crcRegister_L ^ polynomialCode_L);
			}
		}
	}

	return new byte[] { crcRegister_L, crcRegister_H };
}

代码地址:ModbusCrc16

原文地址:https://www.cnblogs.com/victorbu/p/10393061.html