Here's mine; 16 bit; trailing CRC code.
All this depends on the architecture (big vs little Endian).
public static bool HasValidCRC( byte[] buffer, int count ) {
if ( count <= 3 ) {
return false;
}
byte[] bufferCRC =
new byte[] { buffer[ count - 2 ], buffer[ count - 1 ] };
byte[] calculatedCRC =
FunctionBase.CalculateModbusCRC16( buffer, count - 2 );
if ( bufferCRC[ 0 ] != calculatedCRC[ 0 ] ||
bufferCRC[ 1 ] != calculatedCRC[ 1 ] ) {
return false;
}
return true;
}
private static byte[] CalculateModbusCRC16( byte[] packet, int length ) {
ushort crc = 0xFFFF;
for ( int i = 0; i < length; i++ ) {
crc ^= ( ushort ) packet[ i ];
for ( int j = 0; j < 8; j++ ) {
if ( ( crc & 0x0001 ) == 1 ) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}
byte[] crcBytes = BitConverter.GetBytes( crc );
if ( BitConverter.IsLittleEndian == false ) {
crcBytes = ReverseBytes( crcBytes );
}
return crcBytes;
}
private static byte[] ReverseBytes( byte[] inArray ) {
int i = inArray.Length;
byte[] outArray = new byte[ i ];
foreach ( byte b in inArray ) {
i--;
outArray[ i ] = b;
}
return outArray;
}