Computation of cyclic redundancy checks
   HOME

TheInfoList



OR:

Computation of a
cyclic redundancy check A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to digital data. Blocks of data entering these systems get a short ''check value'' attached, based on t ...
is derived from the mathematics of polynomial division, modulo two. In practice, it resembles long division of the
binary Binary may refer to: Science and technology Mathematics * Binary number, a representation of numbers using only two digits (0 and 1) * Binary function, a function that takes two arguments * Binary operation, a mathematical operation that t ...
message string, with a fixed number of zeroes appended, by the "generator polynomial" string except that exclusive or operations replace subtractions. Division of this type is efficiently realised in hardware by a modified shift register, and in software by a series of equivalent
algorithm In mathematics and computer science, an algorithm () is a finite sequence of rigorous instructions, typically used to solve a class of specific Computational problem, problems or to perform a computation. Algorithms are used as specificat ...
s, starting with simple code close to the mathematics and becoming faster (and arguably more
obfuscated Obfuscation is the obscuring of the intended meaning of communication by making the message difficult to understand, usually with confusing and ambiguous language. The obfuscation might be either unintentional or intentional (although intent u ...
) through
byte The byte is a unit of digital information that most commonly consists of eight bits. Historically, the byte was the number of bits used to encode a single character of text in a computer and for this reason it is the smallest addressable unit ...
-wise parallelism and space–time tradeoffs. Various CRC standards extend the polynomial division algorithm by specifying an initial shift register value, a final Exclusive-Or step and, most critically, a bit ordering (
endianness In computing, endianness, also known as byte sex, is the order or sequence of bytes of a word of digital data in computer memory. Endianness is primarily expressed as big-endian (BE) or little-endian (LE). A big-endian system stores the most sig ...
). As a result, the code seen in practice deviates confusingly from "pure" division, and the register may shift left or right.


Example

As an example of implementing polynomial division in hardware, suppose that we are trying to compute an 8-bit CRC of an 8-bit message made of the
ASCII ASCII ( ), abbreviated from American Standard Code for Information Interchange, is a character encoding standard for electronic communication. ASCII codes represent text in computers, telecommunications equipment, and other devices. Because of ...
character "W", which is binary 010101112, decimal 8710, or
hexadecimal In mathematics and computing, the hexadecimal (also base-16 or simply hex) numeral system is a positional numeral system that represents numbers using a radix (base) of 16. Unlike the decimal system representing numbers using 10 symbols, hexa ...
5716. For illustration, we will use the CRC-8-ATM ( HEC) polynomial x^8+x^2+x+1. Writing the first bit transmitted (the coefficient of the highest power of x) on the left, this corresponds to the 9-bit string "100000111". The byte value 5716 can be transmitted in two different orders, depending on the bit ordering convention used. Each one generates a different message polynomial M(x). Msbit-first, this is x^6+x^4+x^2+x+1 = 01010111, while lsbit-first, it is x^7+x^6+x^5+x^3+x = 11101010. These can then be multiplied by x^8 to produce two 16-bit message polynomials x^8 M(x). Computing the remainder then consists of subtracting multiples of the generator polynomial G(x). This is just like decimal long division, but even simpler because the only possible multiples at each step are 0 and 1, and the subtractions borrow "from infinity" instead of reducing the upper digits. Because we do not care about the quotient, there is no need to record it. Observe that after each subtraction, the bits are divided into three groups: at the beginning, a group which is all zero; at the end, a group which is unchanged from the original; and a blue shaded group in the middle which is "interesting". The "interesting" group is 8 bits long, matching the degree of the polynomial. Every step, the appropriate multiple of the polynomial is subtracted to make the zero group one bit longer, and the unchanged group becomes one bit shorter, until only the final remainder is left. In the msbit-first example, the remainder polynomial is x^7+x^5+x. Converting to a hexadecimal number using the convention that the highest power of ''x'' is the msbit; this is A216. In the lsbit-first, the remainder is x^7+x^4+x^3. Converting to hexadecimal using the convention that the highest power of ''x'' is the lsbit, this is 1916.


Implementation

Writing out the full message at each step, as done in the example above, is very tedious. Efficient implementations use an n-bit shift register to hold only the interesting bits. Multiplying the polynomial by x is equivalent to shifting the register by one place, as the coefficients do not change in value but only move up to the next term of the polynomial. Here is a first draft of some
pseudocode In computer science, pseudocode is a plain language description of the steps in an algorithm or another system. Pseudocode often uses structural conventions of a normal programming language, but is intended for human reading rather than machine re ...
for computing an ''n''-bit CRC. It uses a contrived composite data type for polynomials, where ''x'' is not an integer variable, but a
constructor Constructor may refer to: Science and technology * Constructor (object-oriented programming), object-organizing method * Constructors (Formula One), person or group who builds the chassis of a car in auto racing, especially Formula One * Construc ...
generating a ''Polynomial''
object Object may refer to: General meanings * Object (philosophy), a thing, being, or concept ** Object (abstract), an object which does not exist at any particular time or place ** Physical object, an identifiable collection of matter * Goal, an ai ...
that can be added, multiplied and exponentiated. To xor two polynomials is to add them, modulo two; that is, to exclusive OR the coefficients of each matching term from both polynomials. function crc(''bit array'' bitString ..len ''int'' len) :Code fragment 1: Simple polynomial division Note that this example code avoids the need to specify a bit-ordering convention by not using bytes; the input bitString is already in the form of a bit array, and the remainderPolynomial is manipulated in terms of polynomial operations; the multiplication by x could be a left or right shift, and the addition of bitString +n/code> is done to the x^0 coefficient, which could be the right or left end of the register. This code has two disadvantages. First, it actually requires an ''n''+1-bit register to hold the remainderPolynomial so that the x^n coefficient can be tested. More significantly, it requires the bitString to be padded with ''n'' zero bits. The first problem can be solved by testing the x^ coefficient of the remainderPolynomial before it is multiplied by x. The second problem could be solved by doing the last ''n'' iterations differently, but there is a more subtle optimization which is used universally, in both hardware and software implementations. Because the XOR operation used to subtract the generator polynomial from the message is commutative and
associative In mathematics, the associative property is a property of some binary operations, which means that rearranging the parentheses in an expression will not change the result. In propositional logic, associativity is a valid rule of replacement f ...
, it does not matter in what order the various inputs are combined into the remainderPolynomial. And specifically, a given bit of the bitString does not need to be added to the remainderPolynomial until the very last instant when it is tested to determine whether to xor with the generatorPolynomial. This eliminates the need to preload the remainderPolynomial with the first ''n'' bits of the message, as well: function crc(''bit array'' bitString ..len ''int'' len) :Code fragment 2: Polynomial division with deferred message XORing This is the standard bit-at-a-time hardware CRC implementation, and is well worthy of study; once you understand why this computes exactly the same result as the first version, the remaining optimizations are quite straightforward. If remainderPolynomial is only ''n'' bits long, then the x^n coefficients of it and of generatorPolynomial are simply discarded. This is the reason that you will usually see CRC polynomials written in binary with the leading coefficient omitted. In software, it is convenient to note that while one may delay the xor of each bit until the very last moment, it is also possible to do it earlier. It is usually convenient to perform the xor a
byte The byte is a unit of digital information that most commonly consists of eight bits. Historically, the byte was the number of bits used to encode a single character of text in a computer and for this reason it is the smallest addressable unit ...
at a time, even in a bit-at-a-time implementation like this: function crc(''byte array'' string ..len ''int'' len) :Code fragment 3: Polynomial division with bytewise message XORing This is usually the most compact software implementation, used in microcontrollers when space is at a premium over speed.


Bit ordering (endianness)

When implemented in
bit serial In telecommunication and data transmission, serial communication is the process of sending data one bit at a time, sequentially, over a communication channel or computer bus. This is in contrast to parallel communication, where several bits are ...
hardware, the generator polynomial uniquely describes the bit assignment; the first bit transmitted is always the coefficient of the highest power of x, and the last n bits transmitted are the CRC remainder R(x), starting with the coefficient of x^ and ending with the coefficient of x^0, a.k.a. the coefficient of 1. However, when bits are processed a
byte The byte is a unit of digital information that most commonly consists of eight bits. Historically, the byte was the number of bits used to encode a single character of text in a computer and for this reason it is the smallest addressable unit ...
at a time, such as when using
parallel transmission In data transmission, parallel communication is a method of conveying multiple binary digits (bits) simultaneously using multiple conductors. This contrasts with serial communication, which conveys only a single bit at a time; this distinction i ...
, byte framing as in
8B/10B encoding In telecommunications, 8b/10b is a line code that maps 8-bit words to 10-bit symbols to achieve DC balance and bounded disparity, and at the same time provide enough state changes to allow reasonable clock recovery. This means that the diff ...
or
RS-232 In telecommunications, RS-232 or Recommended Standard 232 is a standard originally introduced in 1960 for serial communication transmission of data. It formally defines signals connecting between a ''DTE'' (''data terminal equipment'') such a ...
-style asynchronous serial communication, or when implementing a CRC in
software Software is a set of computer programs and associated documentation and data. This is in contrast to hardware, from which the system is built and which actually performs the work. At the lowest programming level, executable code consists ...
, it is necessary to specify the bit ordering (endianness) of the data; which bit in each byte is considered "first" and will be the coefficient of the higher power of x. If the data is destined for
serial communication In telecommunication and data transmission, serial communication is the process of sending data one bit at a time, sequentially, over a communication channel or computer bus. This is in contrast to parallel communication, where several bits are ...
, it is best to use the bit ordering the data will ultimately be sent in. This is because a CRC's ability to detect burst errors is based on proximity in the message polynomial M(x); if adjacent polynomial terms are not transmitted sequentially, a physical error burst of one length may be seen as a longer burst due to the rearrangement of bits. For example, both
IEEE 802 IEEE 802 is a family of Institute of Electrical and Electronics Engineers (IEEE) standards for local area networks (LAN), personal area network (PAN), and metropolitan area networks (MAN). The IEEE 802 LAN/MAN Standards Committee (LMSC) maintains ...
(
ethernet Ethernet () is a family of wired computer networking technologies commonly used in local area networks (LAN), metropolitan area networks (MAN) and wide area networks (WAN). It was commercially introduced in 1980 and first standardized in 198 ...
) and
RS-232 In telecommunications, RS-232 or Recommended Standard 232 is a standard originally introduced in 1960 for serial communication transmission of data. It formally defines signals connecting between a ''DTE'' (''data terminal equipment'') such a ...
( serial port) standards specify least-significant bit first (little-endian) transmission, so a software CRC implementation to protect data sent across such a link should map the least significant bits in each byte to coefficients of the highest powers of x. On the other hand,
floppy disk A floppy disk or floppy diskette (casually referred to as a floppy, or a diskette) is an obsolescent type of disk storage composed of a thin and flexible disk of a magnetic storage medium in a square or nearly square plastic enclosure lined w ...
s and most
hard drive A hard disk drive (HDD), hard disk, hard drive, or fixed disk is an electro-mechanical data storage device that stores and retrieves digital data using magnetic storage with one or more rigid rapidly rotating platters coated with magnet ...
s write the most significant bit of each byte first. The lsbit-first CRC is slightly simpler to implement in software, so is somewhat more commonly seen, but many programmers find the msbit-first bit ordering easier to follow. Thus, for example, the XMODEM-CRC extension, an early use of CRCs in software, uses an msbit-first CRC. So far, the pseudocode has avoided specifying the ordering of bits within bytes by describing shifts in the pseudocode as multiplications by x and writing explicit conversions from binary to polynomial form. In practice, the CRC is held in a standard binary register using a particular bit-ordering convention. In msbit-first form, the most significant binary bits will be sent first and so contain the higher-order polynomial coefficients, while in lsbit-first form, the least-significant binary bits contain the higher-order coefficients. The above pseudocode can be written in both forms. For concreteness, this uses the 16-bit CRC-16-
CCITT The ITU Telecommunication Standardization Sector (ITU-T) is one of the three sectors (divisions or units) of the International Telecommunication Union (ITU). It is responsible for coordinating standards for telecommunications and Information Commu ...
polynomial x^ + x^ + x^5 + 1: ''// Most significant bit first (big-endian)'' ''// x^16+x^12+x^5+1 = (1) 0001 0000 0010 0001 = 0x1021'' function crc(''byte array'' string ..len ''int'' len) :Code fragment 4: Shift register based division, MSB first ''// Least significant bit first (little-endian)'' ''// x^16+x^12+x^5+1 = 1000 0100 0000 1000 (1) = 0x8408'' function crc(''byte array'' string ..len ''int'' len) :Code fragment 5: Shift register based division, LSB first Note that the lsbit-first form avoids the need to shift string /code> before the xor. In either case, be sure to transmit the bytes of the CRC in the order that matches your chosen bit-ordering convention.


Multi-bit computation


Sarwate algorithm (single lookup table)

Another common optimization uses a
lookup table In computer science, a lookup table (LUT) is an array that replaces runtime computation with a simpler array indexing operation. The process is termed as "direct addressing" and LUTs differ from hash tables in a way that, to retrieve a value v wi ...
indexed by highest order coefficients of rem to process more than one bit of dividend per iteration. Most commonly, a 256-entry lookup table is used, replacing the body of the outer loop (over i) with: // Msbit-first rem = (rem leftShift 8) xor big_endian_table tring[ixor ((leftmost 8 bits of rem) rightShift (n-8))">.html" ;"title="tring[i">tring[ixor ((leftmost 8 bits of rem) rightShift (n-8)) // Lsbit-first rem = (rem rightShift 8) xor little_endian_table tring[ixor (rightmost 8 bits of rem)] :Code fragment 6: Cores of table based division One of the most commonly encountered CRC algorithms is known as CRC-32, used by (among others) Ethernet, FDDI, ZIP (file format), ZIP and other archive formats, and PNG
image format An Image file format is a file format for a digital image. There are many formats that can be used, such as JPEG, PNG, and GIF. Most formats up until 2022 were for storing 2D images, not 3D ones. The data stored in an image file format may be c ...
. Its polynomial can be written msbit-first as 0x04C11DB7, or lsbit-first as 0xEDB88320. The W3C webpage on PNG includes an appendix with a short and simple table-driven implementation in C of CRC-32. You will note that the code corresponds to the lsbit-first byte-at-a-time pseudocode presented here, and the table is generated using the bit-at-a-time code. Using a 256-entry table is usually most convenient, but other sizes can be used. In small microcontrollers, using a 16-entry table to process four bits at a time gives a useful speed improvement while keeping the table small. On computers with ample storage, a -entry table can be used to process 16 bits at a time.


Generating the tables

The software to generate the tables is so small and fast that it is usually faster to compute them on program startup than to load precomputed tables from storage. One popular technique is to use the bit-at-a-time code 256 times to generate the CRCs of the 256 possible 8-bit bytes. However, this can be optimized significantly by taking advantage of the property that table xor j

table xor table /code>. Only the table entries corresponding to powers of two need to be computed directly. In the following example code, crc holds the value of table /code>: big_endian_table := 0 crc := 0x8000 // ''Assuming a 16-bit polynomial'' i := 1 do while i < 256 :Code fragment 7: Byte-at-a-time CRC table generation, MSB first little_endian_table := 0 crc := 1; i := 128 do while i > 0 :Code fragment 8: Byte-at-a-time CRC table generation, LSB first In these code samples, the table index i + j is equivalent to i xor j; you may use whichever form is more convenient.


CRC-32 algorithm

This is a practical algorithm for the CRC-32 variant of CRC. The CRCTable is a
memoization In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again. Memoization ...
of a calculation that would have to be repeated for each byte of the message (). Function CRC32 Input: data: Bytes // Array of bytes Output: crc32: UInt32 // 32-bit unsigned CRC-32 value
// Initialize CRC-32 to starting value crc32 ← 0xFFFFFFFF
for each byte in data do nLookupIndex ← (crc32 xor byte) and 0xFF crc32 ← (crc32 shr 8) xor CRCTable LookupIndex // CRCTable is an array of 256 32-bit constants
// Finalize the CRC-32 value by inverting all the bits crc32 ← crc32 xor 0xFFFFFFFF return crc32 In C, the algorithm looks as such: #include // uint32_t, uint8_t uint32_t CRC32(const uint8_t data[], size_t data_length)


Byte-Slicing using multiple tables

There exists a slice-by-N (typically slice-by-8 for CRC32; N ≤ 64) algorithm that usually doubles or triples the performance compared to the Sarwate algorithm. Instead of reading 8 bits at a time, the algorithm reads 8N bits at a time. Doing so maximizes performance on
superscalar A superscalar processor is a CPU that implements a form of parallelism called instruction-level parallelism within a single processor. In contrast to a scalar processor, which can execute at most one single instruction per clock cycle, a sup ...
processors. It is unclear who actually invented the algorithm.


Parallel computation without table

Parallel update for a byte or a word at a time can also be done explicitly, without a table. This is normally used in high-speed hardware implementations. For each bit an equation is solved after 8 bits have been shifted in. The following tables list the equations for some commonly used polynomials, using following symbols:


Two-step computation

As the CRC-32 polynomial has a large number of terms, when computing the remainder a byte at a time each bit depends on several bits of the previous iteration. In byte-parallel hardware implementations this calls for either multiple-input or cascaded XOR gates which increases propagation delay. To maximise computation speed, an ''intermediate remainder'' can be calculated by passing the message through a 123-bit shift register. The polynomial is a carefully selected multiple of the standard polynomial such that the terms (feedback taps) are widely spaced, and no bit of the remainder is XORed more than once per byte iteration. Thus only two-input XOR gates, the fastest possible, are needed. Finally the intermediate remainder is divided by the standard polynomial in a second shift register to yield the CRC-32 remainder.


Block-wise computation

Block-wise computation of the remainder can be performed in hardware for any CRC polynomial by factorizing the State Space transformation matrix needed to compute the remainder into two simpler Toeplitz matrices.


One-pass checking

When appending a CRC to a message, it is possible to detach the transmitted CRC, recompute it, and verify the recomputed value against the transmitted one. However, a simpler technique is commonly used in hardware. When the CRC is transmitted with the correct byte order (matching the chosen bit-ordering convention), a receiver can compute an overall CRC, over the message ''and'' the CRC, and if they are correct, the result will be zero. This possibility is the reason that most network protocols that include a CRC do so ''before'' the ending delimiter; it is not necessary to know whether the end of the packet is imminent to check the CRC. In fact, a few protocols use the CRC *as* the ending delimiter -- CRC-based framing.


CRC variants

In practice, most standards specify presetting the register to all-ones and inverting the CRC before transmission. This has no effect on the ability of a CRC to detect changed bits, but gives it the ability to notice bits that are added to the message.


Preset to −1

The basic mathematics of a CRC accepts (considers as correctly transmitted) messages which, when interpreted as a polynomial, are a multiple of the CRC polynomial. If some leading 0 bits are prepended to such a message, they will not change its interpretation as a polynomial. This is equivalent to the fact that 0001 and 1 are the same number. But if the message being transmitted does care about leading 0 bits, the inability of the basic CRC algorithm to detect such a change is undesirable. If it is possible that a transmission error could add such bits, a simple solution is to start with the rem shift register set to some non-zero value; for convenience, the all-ones value is typically used. This is mathematically equivalent to complementing (binary NOT) the first ''n'' bits of the message, where ''n'' is the number of bits in the CRC register. This does not affect CRC generation and checking in any way, as long as both generator and checker use the same initial value. Any non-zero initial value will do, and a few standards specify unusual values,E.g. low-frequency RFID but the all-ones value (−1 in twos complement binary) is by far the most common. Note that a one-pass CRC generate/check will still produce a result of zero when the message is correct, regardless of the preset value.


Post-invert

The same sort of error can occur at the end of a message, albeit with a more limited set of messages. Appending 0 bits to a message is equivalent to multiplying its polynomial by ''x'', and if it was previously a multiple of the CRC polynomial, the result of that multiplication will be, as well. This is equivalent to the fact that, since 726 is a multiple of 11, so is 7260. A similar solution can be applied at the end of the message, inverting the CRC register before it is appended to the message. Again, any non-zero change will do; inverting all the bits (XORing with an all-ones pattern) is simply the most common. This has an effect on one-pass CRC checking: instead of producing a result of zero when the message is correct, it produces a fixed non-zero result. (To be precise, the result is the CRC (without non-zero preset, but with post-invert) of the inversion pattern.) Once this constant has been obtained (most easily by performing a one-pass CRC generate/check on an arbitrary message), it can be used directly to verify the correctness of any other message checked using the same CRC algorithm.


See also

General category * Error correcting code *
List of hash functions This is a list of hash functions, including cyclic redundancy checks, checksum functions, and cryptographic hash functions. Cyclic redundancy checks Adler-32 is often mistaken for a CRC, but it is not: it is a checksum. Checksums Universa ...
*
Parity Parity may refer to: * Parity (computing) ** Parity bit in computing, sets the parity of data for the purpose of error detection ** Parity flag in computing, indicates if the number of set bits is odd or even in the binary representation of the r ...
is equivalent to a 1-bit CRC with polynomial . Non-CRC checksums * Adler-32 * Fletcher's checksum


References


External links

* * {{cite web , url=https://github.com/lizardfs/lizardfs/tree/master/external/crcutil-1.0 , title=Efficient (~1 CPU cycle per byte) CRC implementation , author=Andrew Kadarch, Bob Jenkins, website=
GitHub GitHub, Inc. () is an Internet hosting service for software development and version control using Git. It provides the distributed version control of Git plus access control, bug tracking, software feature requests, task management, continuous ...
Cyclic redundancy checks Finite fields Articles with example pseudocode