private void Encode(uint crcInitialValue = 0x0) { var bytes = new List <byte>(); var frameControlByte0 = (byte)Type; if (FramePending) { frameControlByte0 |= (0x1 << 4); } bytes.Add(frameControlByte0); bytes.Add(0); // frameControlByte1 bytes.Add(DataSequenceNumber); if (AddressInformation != null && AddressInformation.Bytes.Count > 0) { bytes.AddRange(AddressInformation.Bytes); } if (Payload != null && Payload.Count > 0) { bytes.AddRange(Payload); } var crcLength = CRCPolynomial.GetLength(); var crc = CalculateCRC(bytes, crcInitialValue, CRCPolynomial); switch (crcLength) { case 2: bytes.Add(crc[0]); bytes.Add(crc[1]); break; case 4: bytes.Add(crc[0]); bytes.Add(crc[1]); bytes.Add(crc[2]); bytes.Add(crc[3]); break; default: Logger.Log(LogLevel.Error, "Cannot generate CRC of invalid length {0}, the packet will not contain CRC data", crcLength); break; } Bytes = bytes.ToArray(); }
public bool CheckCRC(uint crcInitialValue = 0x0) { var crcLength = CRCPolynomial.GetLength(); var crc = CalculateCRC(Bytes.Take(Bytes.Length - crcLength), crcInitialValue, CRCPolynomial); // Byte little endian order switch (crcLength) { case 2: return(Bytes[Bytes.Length - 2] == crc[0] && Bytes[Bytes.Length - 1] == crc[1]); case 4: return(Bytes[Bytes.Length - 4] == crc[0] && Bytes[Bytes.Length - 3] == crc[1] && Bytes[Bytes.Length - 2] == crc[2] && Bytes[Bytes.Length - 1] == crc[3]); default: Logger.Log(LogLevel.Error, "Cannot check CRC of invalid length {0}", crcLength); return(false); } }
/// <summary> /// Generates a CRC using a common polynomial for the next closest bitlength above that specified. /// For example, a bit length of 13 through 16 will use the CCITT16 polynomial masking off bits necessary to maintain the specified bitlength. /// </summary> /// <param name="data">Data to generate a CRC for</param> /// <param name="offset">The offset into the source data at which to start the CRC</param> /// <param name="length">The number of bytes in the source data to analyze</param> /// <param name="polynomial">Standard polynomial to use for the CRC</param> /// <param name="seedCRC">CRC seed value</param> /// <returns>The CRC</returns> /// <returns></returns> public static ulong GenerateChecksum(byte[] data, int offset, int length, CRCPolynomial polynomial, ulong seedCRC) { int bits = 0; switch (polynomial) { case CRCPolynomial.CRC_8: bits = 8; break; case CRCPolynomial.CRC_10: bits = 10; break; case CRCPolynomial.CRC_12: bits = 12; break; case CRCPolynomial.CRC_16: case CRCPolynomial.CRC_16ARC: case CRCPolynomial.CRC_CCITT16: bits = 16; break; case CRCPolynomial.CRC_24: bits = 24; break; case CRCPolynomial.CRC_CCITT32: case CRCPolynomial.CRC_32: bits = 32; break; case CRCPolynomial.CRC_64: bits = 64; break; } return(GenerateChecksum(data, offset, length, bits, (ulong)polynomial, seedCRC)); }
public static ulong GenerateChecksum(byte[] data, int crcBitLength, CRCPolynomial polynomial) { return(GenerateChecksum(data, crcBitLength, (ulong)polynomial, 0)); }
public static ulong GenerateChecksum(byte[] data, int crcBitLength, CRCPolynomial polynomial) { return GenerateChecksum(data, crcBitLength, (ulong)polynomial, 0L); }
public static ulong GenerateChecksum(byte[] data, int offset, int length, CRCPolynomial polynomial, ulong seedCRC) { int crcBitLength = 0; switch (polynomial) { case CRCPolynomial.CRC_10: crcBitLength = 10; break; case CRCPolynomial.CRC_12: crcBitLength = 12; break; case CRCPolynomial.CRC_CCITT16: case CRCPolynomial.CRC_16ARC: case CRCPolynomial.CRC_16: crcBitLength = 0x10; break; case CRCPolynomial.CRC_64: crcBitLength = 0x40; break; case CRCPolynomial.CRC_8: crcBitLength = 8; break; case CRCPolynomial.CRC_24: crcBitLength = 0x18; break; case CRCPolynomial.CRC_32: case CRCPolynomial.CRC_CCITT32: crcBitLength = 0x20; break; } return GenerateChecksum(data, offset, length, crcBitLength, (ulong)polynomial, seedCRC); }