1. 程式人生 > >CRC校驗的精彩介紹(A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS)

CRC校驗的精彩介紹(A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS)

水平有限,不敢翻譯,褻瀆了好文章

A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS

Contents:

[Document Version: 3.00][Last Updated: 9/24/96]

"Everything you wanted to know about CRC algorithms, but were afraidto ask for fear that errors in your understanding might be detected."

  • Author : Ross N. Williams
  • Date : 19 August 1993
  • Version : 3.00
  • Company : Rocksoft(tm) Pty Ltd
  • Snail : 16 Lerwick Avenue, Hazelwood Park 5066, Australia
  • Fax : +61 8 373-4911 (c/- Internode Systems Pty Ltd)
  • Phone : +61 8 379-9217 (10am to 10pm Adelaide Australia time)
  • Note : "Rocksoft" is a trademark of Rocksoft Pty Ltd, Australia
  • Status: Copyright (C) Ross Williams, 1993,1994,1995,1996. However, permission isgranted to make and distribute verbatim copies of thisdocument provided that this information block and copyrightnotice is included. Also, the C code modules includedin this document are fully PUBLIC DOMAIN (PD)
    .
  • Thanks: Thanks to Jean-loup Gailly ([email protected]) and Mark Adler ([email protected]) who both proof read this document and picked outlots of nits as well as some big fat bugs.

C sources to are referenced in this document:

This document explains CRCs (Cyclic Redundancy Codes) and theirtable-driven implementations in full, precise detail. Much of theliterature on CRCs, and in particular on their table-drivenimplementations, is a little obscure (or at least seems so to me).This document is an attempt to provide a clear and simple no-nonsenseexplanation of CRCs and to absolutely nail down every detail of theoperation of their high-speed implementations. In addition to this,this document presents a parameterized model CRC algorithm called the"Rocksoft^tm Model CRC Algorithm". The model algorithm can beparameterized to behave like most of the CRC implementations around,and so acts as a good reference for describing particular algorithms.A low-speed implementation of the model CRC algorithm is provided inthe C programming language. Lastly there is a section giving two formsof high-speed table driven implementations, and providing a programthat generates CRC lookup tables.

The aim of an error detection technique is to enable the receiver of amessage transmitted through a noisy (error-introducing) channel todetermine whether the message has been corrupted. To do this, thetransmitter constructs a value (called a checksum) that is a functionof the message, and appends it to the message. The receiver can thenuse the same function to calculate the checksum of the receivedmessage and compare it with the appended checksum to see if themessage was correctly received. For example, if we chose a checksumfunction which was simply the sum of the bytes in the message mod 256(i.e. modulo 256), then it might go something as follows. All numbersare in decimal.

   Message                    :  6 23  4

   Message with checksum      :  6 23  4 33

   Message after transmission :  6 27  4 33

In the above, the second byte of the message was corrupted from 23 to27 by the communications channel. However, the receiver can detectthis by comparing the transmitted checksum (33) with the computerchecksum of 37 (6 + 27 + 4). If the checksum itself is corrupted, acorrectly transmitted message might be incorrectly identified as acorrupted one. However, this is a safe-side failure. A dangerous-sidefailure occurs where the message and/or checksum is corrupted in amanner that results in a transmission that is internally consistent.Unfortunately, this possibility is completely unavoidable and the bestthat can be done is to minimize its probability by increasing theamount of information in the checksum (e.g. widening the checksum fromone byte to two bytes).

Other error detection techniques exist that involve performing complextransformations on the message to inject it with redundantinformation. However, this document addresses only CRC algorithms,which fall into the class of error detection algorithms that leave thedata intact and append a checksum on the end. i.e.:

      <original intact message> <checksum>

In the checksum example in the previous section, we saw how acorrupted message was detected using a checksum algorithm that simplysums the bytes in the message mod 256:

   Message                    :  6 23  4

   Message with checksum      :  6 23  4 33

   Message after transmission :  6 27  4 33

A problem with this algorithm is that it is too simple. If a number ofrandom corruptions occur, there is a 1 in 256 chance that they willnot be detected. For example:

   Message                    :  6 23  4

   Message with checksum      :  6 23  4 33

   Message after transmission :  8 20  5 33

To strengthen the checksum, we could change from an 8-bit register toa 16-bit register (i.e. sum the bytes mod 65536 instead of mod 256) soas to apparently reduce the probability of failure from 1/256 to1/65536. While basically a good idea, it fails in this case becausethe formula used is not sufficiently "random"; with a simple summingformula, each incoming byte affects roughly only one byte of thesumming register no matter how wide it is. For example, in the secondexample above, the summing register could be a Megabyte wide, and theerror would still go undetected. This problem can only be solved byreplacing the simple summing formula with a more sophisticated formulathat causes each incoming byte to have an effect on the entirechecksum register.

Thus, we see that at least two aspects are required to form a strongchecksum function:

WIDTH
A register width wide enough to provide a low a-prioriprobability of failure (e.g. 32-bits gives a 1/2^32 chance of failure).
CHAOS
A formula that gives each input byte the potential to change any number of bits in the register.

Note: The term "checksum" was presumably used to describe earlysumming formulas, but has now taken on a more general meaningencompassing more sophisticated algorithms such as the CRC ones. TheCRC algorithms to be described satisfy the second condition very well,and can be configured to operate with a variety of checksum widths.

Where might we go in our search for a more complex function thansumming? All sorts of schemes spring to mind. We could constructtables using the digits of pi, or hash each incoming byte with all thebytes in the register. We could even keep a large telephone bookon-line, and use each incoming byte combined with the register bytesto index a new phone number which would be the next register value.The possibilities are limitless.

However, we do not need to go so far; the next arithmetic stepsuffices. While addition is clearly not strong enough to form aneffective checksum, it turns out that division is, so long as thedivisor is about as wide as the checksum register.

The basic idea of CRC algorithms is simply to treat the message as anenormous binary number, to divide it by another fixed binary number,and to make the remainder from this division the checksum. Uponreceipt of the message, the receiver can perform the same division andcompare the remainder with the "checksum" (transmitted remainder).

Example: Suppose the the message consisted of the two bytes (6,23) asin the previous example. These can be considered to be the hexadecimalnumber 0617 which can be considered to be the binary number0000-0110-0001-0111. Suppose that we use a checksum register one-bytewide and use a constant divisor of 1001, then the checksum is theremainder after 0000-0110-0001-0111 is divided by 1001. While in thiscase, this calculation could obviously be performed using commongarden variety 32-bit registers, in the general case this is messy. Soinstead, we'll do the division using good-'ol long division which youlearned in school (remember?). Except this time, it's in binary:

          ...0000010101101 = 00AD =  173 = QUOTIENT

         ____-___-___-___-

9= 1001 ) 0000011000010111 = 0617 = 1559 = DIVIDEND

DIVISOR   0000.,,....,.,,,

          ----.,,....,.,,,

           0000,,....,.,,,

           0000,,....,.,,,

           ----,,....,.,,,

            0001,....,.,,,

            0000,....,.,,,

            ----,....,.,,,

             0011....,.,,,

             0000....,.,,,

             ----....,.,,,

              0110...,.,,,

              0000...,.,,,

              ----...,.,,,

               1100..,.,,,

               1001..,.,,,

               ====..,.,,,

                0110.,.,,,

                0000.,.,,,

                ----.,.,,,

                 1100,.,,,

                 1001,.,,,

                 ====,.,,,

                  0111.,,,

                  0000.,,,

                  ----.,,,

                   1110,,,

                   1001,,,

                   ====,,,

                    1011,,

                    1001,,

                    ====,,

                     0101,

                     0000,

                     ----

                      1011

                      1001

                      ====

                      0010 = 02 = 2 = REMAINDER

In decimal this is "1559 divided by 9 is 173 with a remainder of 2".

Although the effect of each bit of the input message on the quotientis not all that significant, the 4-bit remainder gets kicked aboutquite a lot during the calculation, and if more bytes were added tothe message (dividend) it's value could change radically again veryquickly. This is why division works where addition doesn't.

In case you're wondering, using this 4-bit checksum the transmittedmessage would look like this (in hexadecimal): 06172 (where the 0617is the message and the 2 is the checksum). The receiver would divide0617 by 9 and see whether the remainder was 2.

While the division scheme described in the previous section is veryvery similar to the checksumming schemes called CRC schemes, the CRCschemes are in fact a bit weirder, and we need to delve into somestrange number systems to understand them.

The word you will hear all the time when dealing with CRC algorithmsis the word "polynomial". A given CRC algorithm will be said to beusing a particular polynomial, and CRC algorithms in general are saidto be operating using polynomial arithmetic. What does this mean?

Instead of the divisor, dividend (message), quotient, and remainder(as described in the previous section) being viewed as positiveintegers, they are viewed as polynomials with binary coefficients.This is done by treating each number as a bit-string whose bits arethe coefficients of a polynomial. For example, the ordinary number 23(decimal) is 17 (hex) and 10111 binary and so it corresponds to thepolynomial:

   1*x^4 + 0*x^3 + 1*x^2 + 1*x^1 + 1*x^0

or, more simply:

   x^4 + x^2 + x^1 + x^0

Using this technique, the message, and the divisor can be representedas polynomials and we can do all our arithmetic just as before, exceptthat now it's all cluttered up with Xs. For example, suppose we wantedto multiply 1101 by 1011. We can do this simply by multiplying thepolynomials:

(x^3 + x^2 + x^0)(x^3 + x^1 + x^0)

= (x^6 + x^4 + x^3

 + x^5 + x^3 + x^2

 + x^3 + x^1 + x^0) = x^6 + x^5 + x^4 + 3*x^3 + x^2 + x^1 + x^0

At this point, to get the right answer, we have to pretend that x is 2and propagate binary carries from the 3*x^3 yielding:

   x^7 + x^3 + x^2 + x^1 + x^0

It's just like ordinary arithmetic except that the base is abstractedand brought into all the calculations explicitly instead of beingthere implicitly. So what's the point?

The point is that IF we pretend that we DON'T know what x is, we CAN'Tperform the carries. We don't know that 3*x^3 is the same as x^4 + x^3because we don't know that x is 2. In this true polynomial arithmeticthe relationship between all the coefficients is unknown and so thecoefficients of each power effectively become strongly typed;coefficients of x^2 are effectively of a different type tocoefficients of x^3.

With the coefficients of each power nicely isolated, mathematicianscame up with all sorts of different kinds of polynomial arithmeticssimply by changing the rules about how coefficients work. Of theseschemes, one in particular is relevant here, and that is a polynomialarithmetic where the coefficients are calculated MOD 2 and there is nocarry; all coefficients must be either 0 or 1 and no carries arecalculated. This is called "polynomial arithmetic mod 2". Thus,returning to the earlier example:

(x^3 + x^2 + x^0)(x^3 + x^1 + x^0)

= (x^6 + x^4 + x^3

 + x^5 + x^3 + x^2

 + x^3 + x^1 + x^0)

= x^6 + x^5 + x^4 + 3*x^3 + x^2 + x^1 + x^0

Under the other arithmetic, the 3*x^3 term was propagated using thecarry mechanism using the knowledge that x=2. Under "polynomialarithmetic mod 2", we don't know what x is, there are no carries, andall coefficients have to be calculated mod 2. Thus, the resultbecomes:

= x^6 + x^5 + x^4 + x^3 + x^2 + x^1 + x^0

As Knuth [Knuth81] says (p.400):

"The reader should note the similarity between polynomial arithmetic and multiple-precision arithmetic (Section 4.3.1), where the radix b is substituted for x. The chief difference is that the coefficient u_k of x^k in polynomial arithmetic bears little or no relation to its neighboring coefficients x^{k-1} [and x^{k+1}], so the idea of "carrying" from one place to another is absent. In fact polynomial arithmetic modulo b is essentially identical to multiple precision arithmetic with radix b, except that all carries are suppressed."

Thus polynomical arithmetic mod 2 is just binary arithmetic mod 2 withno carries. While polynomials provide useful mathematical machinery inmore analytical approaches to CRC and error-correction algorithms, forthe purposes of exposition they provide no extra insight and someencumbrance and have been discarded in the remainder of this documentin favour of direct manipulation of the arithmetical system with whichthey are isomorphic: binary arithmetic with no carry.

Please check attribution section for Author of this document!This article was written by [email protected][mailto]. The mostrecent version is available on the WWW serverhttp://www.repairfaq.org/filipg/[Copyright][Disclaimer]