Crc

Files CCore/inc/Crc.h CCore/src/Crc.cpp

There are three Crc classes: Crc16, Crc24, Crc32 to calculate a CRC value of a byte sequence. Technically, CRC is a polynomial division reminder. It is used to control sudden errors in a byte stream. There are 3 popular and standard such CRC, widely used in IT. We call them Crc16, Crc24 and Crc32 by the number of output bits. In practical applications they are used with some adjustments, i.e. the byte sequence is extended with some start sequence in order to calculate its CRC.

CCore uses a generic implementation of CRC based on lookup tables. So Crc16, Crc24, Crc32 are instantiations of the generic CrcAccumulator class, parametrized by the Algorithm Packages AlgoCrc16, AlgoCrc24, AlgoCrc32:


/* struct AlgoCrc16 */ 

struct AlgoCrc16
 {
  using ResultType = uint16 ;

  using DataType = uint8 ;
  
  static ResultType Add(ResultType crc,DataType data);
   
  static ResultType Mask(ResultType crc);
   
  static const uint16 Table[256];
 };
 
/* struct AlgoCrc24 */ 

struct AlgoCrc24
 {
  using ResultType = uint32 ;

  using DataType = uint8 ;
  
  static ResultType Add(ResultType crc,DataType data);
   
  static const ResultType BitMask = 0xFFFFFF ;

  static ResultType Mask(ResultType crc);
   
  static const uint32 Table[256];
 };
 
/* struct AlgoCrc32 */ 

struct AlgoCrc32
 {
  using ResultType = uint32 ;

  using DataType = uint8 ;
  
  static ResultType Add(ResultType crc,DataType data);
   
  static ResultType Mask(ResultType crc);
  
  static const uint32 Table[256];
 };

CrcAccumulator is an "accumulator" class:


template <class Algo>
class CrcAccumulator
 {
  public:
  
   using ResultType = typename Algo::ResultType ;

   using DataType = typename Algo::DataType ;
   
  private:
  
   ResultType crc;
   
  public:
  
   explicit CrcAccumulator(ResultType crc_=1);
   
   operator ResultType() const { return crc; }
   
   void add(DataType data);
   
   template <class R>
   void addRange(R r); 
 };

/* types */  

using Crc16 = CrcAccumulator<AlgoCrc16> ;

using Crc24 = CrcAccumulator<AlgoCrc24> ;

using Crc32 = CrcAccumulator<AlgoCrc32> ;

You can built the result by "feeding" the object of this class by pieces of data. You can put bytes one-by-one or add by ranges. The type R in the method addRange() must be a Cursor over a piece of data. By default, CrcAccumulator starts from the value 1. An example:


PtrLen<uint8> data=....;

Crc32 crc;

crc.addRange(data);

uint32 result=crc;