CRC Basics

Created by Jeremy Purcell, last modified on Jun 22, 2012

Features

  • Basic explanation of CRC (appending zeros method)
  • Short discussion on brute force calculation of CRC
  • Examples of calculating a CRC sum
  • C code for simple implementation of CRC

Introduction

A Cyclic Redundancy Check (CRC) is a verification method used to ensure that data being sent is not corrupted during transfer. The use of CRCs is common in communication mediums that transmit digital data, such as WiFi and Ethernet. There is a need to check for communication errors in embedded systems, as technology drives them to be capable of creating and sending larger data packets in a faster and more complex manner. This application note discusses a method for computing and verifying a CRC.

Background

The CRC algorithm computes a checksum for each specific data set that is sent through it. This algorithm utilizes a polynomial key and the transferred data.

The sending system calculates the check or verification code and appends it to the outgoing message. On the receiving end, the data is put through the same process. If the CRC produced at the receiving end does not match the sent CRC, then the data is possibly corrupt. The receiver can request that the data be retransmitted or simply ignore the data. When the CRC matches the received version, the user can be fairly confident that the transmission is not corrupted.

Implementing CRCs is accomplished using two different methods. The brute force method requires more computational resources and can be more time consuming. The lookup table method requires more memory resources and is useful for defined and/or repetitive data sets.

Application

This application discusses the brute force method of computing CRCs. CRC math can be accomplished in software by shifting the data or shifting the polynomial key, then performing the computations. There are several implementations that compute the CRC checksum.

CRC Polynomial

The polynomial key is an important part of the CRC. Keys are not just random polynomials; they are generated using a set of mathematical formulas and are intended to increase the number of mistakes that the CRC process identifies. The polynomial is typically defined by the network protocol or external device. Since there is a well-established set of keys available, the processes for defining keys is not discussed here.

The polynomial key is translated into a binary expression. This is done by expanding the polynomial, and then taking the coefficients. An example polynomial to binary translation is shown below.

Polynomial key: image

Expanded polynomial key: image

Polynomial coefficients: 100110001

The highest power of the polynomial shown is eight, which makes this polynomial an 8-bit CRC, commonly referred to as CRC-8. Four, eight, sixteen, and thirty-two bit are very common polynomial sizes used in CRCs.

Computing a CRC Checksum

The sending device calculates the CRC by appending the data with the correct number of zeros. The data is then processed using binary math before sending it over the communication channel. This method is the “appended zeros” implementation show in Figure 1. Example 1 in the Appendix demonstrates this technique.

First, zeros are appended to the full packet of data. Align the polynomial with the leftmost 1 in the data. The data is XORed with the polynomial. The result is the new data. Again align the polynomial with the leftmost 1 in the data. The process continues until the data is smaller then the polynomial. This CRC is added to the data stream before transmission.


Figure 1. Appending Zeros Algorithm

CRC Verification

On the receiving side of the system, there are two methods explained here for verifying the CRC: the “appended zeros” implementation or the “zero result” implementation.

In the “appended zeros” implementation, the CRC is removed, and the data is appended with n zeros, where n is the highest power of the polynomial. With CRC-8, eight zeros are appended to the end of the data. The CRC is then calculated as show in Figure 1 and compared with the CRC value received.

In the “zero result” implementation, a similar process to that shown in Figure 1 is followed, except zeros are not appended, and data includes the received CRC. Once the process is complete, the result equals zero if the data matches the CRC. Example 2 in the Appendix demonstrates this technique.

Many applications use a lookup table, since they require fewer computational resources. These lookup tables contain CRC values that correspond to specific data sets. This method is effective for applications with defined and/or repetitive data transmissions.

Considerations

Endianness is the term used to describe the byte order of the data. Big-endian means that data is being sent with the most significant bit (MSB) first. Conversely, little-endian is sent with the least significant bit (LSB) first. Endianness matters, because the CRC changes when the byte is flipped from MSB first to LSB first. Typically, the endianess is determined by the type of data being transferred.

Conclusion

A CRC is a simple but effective way to check for errors in data being sent over a noisy medium. This application note discussed how CRCs work and presented methods for calculating and verifying them. A CRC can be easily incorporated into most embedded systems.

Appendix: Examples

Example 1: Appended Zeros Method

The incoming data MSB first is 01101010 10101111 (two bytes). This example uses the polynomial key: x8 + x2 + x1 + 1 or 100000111. For the CRC-8, which is 8-bit, the key is actually 9 bits.

011010101010111100000000  Data appended with 8 zeros
100000111                 Right shift polynomial key
011010101010111100000000
 100000111                XOR data with key and right shift
 01010110110111100000000
  100000111               XOR and right shift
  0010111000111100000000
   100000111              Right shift
   010111000111100000000
    100000111             XOR and right shift
    00111011011100000000
     100000111            Right shift
     0111011011100000000
      100000111           XOR and right shift
      011011100100000000
       100000111          XOR and right shift
       0101111100000000
        100000111         XOR and right shift
        0011110110000000
         100000111        Right shift
         011110110000000
          100000111       XOR and right shift
          01110101100000
           100000111      XOR and right shift
           0110100010000
            100000111     XOR and right shift
            010100101000
             100000111    XOR and right shift
             00100110100
              100000111   Right shift
              0100110100
               100000111  XOR
               000110011  Result < Polynomial Key

The resulting check for the data 0x6AAF is 0x33. In this example, the data stream out of the transmitter (in HEX) is 34 (xx) 6A AF 33. The first byte(s) are protocols for transmission, the next two bytes are the data, and the last byte is the CRC.

Example 2: Zero Result Method

The incoming data MSB first is 01101010 10101111 (two bytes). This example uses the polynomial key: x8 + x2 + x1 + 1 or 100000111. For the CRC-8, which is 8-bit, the key is actually 9 bits.

011010101010111100110011   Data and CRC received
100000111                  Right shift polynomial key
011010101010111100110011
 100000111                 XOR data with key and right shift
 01010110110111100110011
  100000111                XOR and right shift
  0010111000111100110011
   100000111               Right shift
   010111000111100110011
    100000111              XOR and right shift
    00111011011100110011
     100000111             Right shift
     0111011011100110011
      100000111            XOR and right shift
      011011100100110011
       100000111           XOR and right shift
       01011111000110011
        100000111          XOR and right shift
         0011110110110011
          100000111        Right shift
          011110110110011
           100000111       XOR and right shift
           01110101010011
            100000111      XOR and right shift
            0110100100011
             100000111     XOR and right shift
             010100011011
              100000111    XOR and right shift
              00100000111
               100000111   Right shift
               0100000111
                100000111  XOR
                000000000  Result < polynomial Key

The check for 0x6AAF is 0x00 using the “zero result method,” which confirms that the proper data was received.

Questions/Comments

Any questions or comments please go to Digi-Key’s TechForum