Http://www.repairfaq.org/filipg/LINK/F_crc_v31.html
Contents:
- [Sub-toc] for this document | main [Table 'o contents]
- 1. Preface
- 1.1) about the author & Copyright
- 1.2) Abstract
- 2. Introduction: Error Detection
- 3. The need for complexity
- 4. The basic idea behind CRC Algorithms
- 5. Polynomical Arithmetic
- Jump to [next] segment
[Document version:3.00] [Last updated:9/24/96]
1. Preface 1.1) about the author & Copyright
"Everything you wanted to know about CRC algorithms, but were afraid to ask for fear that errors in your understanding might be detected ."
- Author: Ross N. Williams
- E-mail: ross@guest.adelaide.edu.au
- Date: 19 August 1993
- Version: 3.00
- FTP: ftp.adelaide.edu. au/pub/rocksoft/crc_v3.txt
- Www: http://www.on.net/clients/rocksoft/rocksoft/
- Company: rocksoft (TM) Pty Ltd
- Snail Il: 16 Lerwick Avenue, hazelwood Park 5066, Australia
- Fax: + 61 8 373-4911 (C/-internode Systems Pty Ltd)
- Phone: + 61 8 379-9217 (10 am to 10 pm adelide Australia time)
- Note: "rocksoft" is a trademark of rocksoft Pty Ltd, Australia
- Status: Copyright (c) Ross Williams, 1993,1994, 1995,1996. However, permission is granted to make and distribute verbatim copies of this document provided that this information block and copyright notice is already ded. Also,The C code modules encoded in this document are fully public domain (PD).
- Thanks: Thanks to Jean-Loup gailly (jloup@chorus.fr) and Mark Adler (me@quest.jpl.nasa.gov) who both proof read this document and picked out lots of nits as well as some big fat bugs.
C sources to are referenced in this document:
- Crcmodel. H (0 KB)
- Crcmodel. C (0 KB)
- Crctable. C (0 KB)
1.2) Abstract
This document explains CRCs (Cyclic Redundancy codes) and their table-driven implementations in full, precise detail. much of the literature on CRCs, and in particle on their table-driven implementations, is a little obscure (or at least seems so to me ). this document is an attempt to provide a clear and simple no-nonsense explanation of CRCs and to absolutely nail down every detail of the operation 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 be parameterized to behave like most of the CRC implementations around, and so acts as a good reference for describing fig. A low-speed implementation of the model CRC algorithm is provided in the C programming language. lastly there is a section giving two forms of high-speed table driven implementations, and providing a program that generates CRC Lookup tables.
2. Introduction: Error Detection
The aim of an error detection technique is to enable the attacker of a message transmitted through a noisy (error-introducing) channel to determine whether the message has been upted. to do this, the transmitter constructs a value (called a checksum) That is a function of the message, and appends it to the message. the specified er can be then use the same function to calculate the checksum of the specified ed message and compare it with the appended checksum to see if the message was correctly received ed. for example, if we chose a checksum function 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 numbers are 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 has upted from 23 to 27 by the communications channel. however, the attacker can detect this by comparing the transmitted checksum (33) with the computer checksum of 37 (6 + 27 + 4 ). if the checksum itself is already upted, a correctly transmitted message might be incorrectly identified as a previous upted one. however, this is a safe-side failure. A dangerous-side failure occurs where the message and/or checksum is already upted in a manner that results in a transmission that is internally consistent. unfortunately, this possibility is completely unavoidable and the best that can be done is to minimize its probability by increasing the amount of information in the checksum (e.g. widening the checksum from one byte to two bytes ).
Other error detection techniques exist that involve implements complex transformations on the message to inject it with redundant information. however, this document addresses only CRC algorithms, which fall into the class of error detection algorithms that leave the data intact and append a checksum on the end. i. e.:
<original intact message> <checksum>
3. The need for complexity
In the checksum example in the previous section, we saw how a completed upted message was detected using a checksum algorithm that simply sums 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 of random conditions uptions occur, there is a 1 in 256 chance that they will not 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 cocould change from an 8-bit register to a 16-bit register (I. e. sum the bytes mod 65536 instead of MOD 256) so as to apparently reduce the probability of failure from 1/256 to 1/65536. while basically a good idea, it fails in this case because the formula used is not sufficiently "random"; with a simple summing formula, each incoming byte affects roughly only one byte of the summing register no matter how wide it is. for example, in the second example above, the summing register cocould be a megabyte wide, and the error wowould still go undetected. this problem can only be solved by replacing the simple summing formula with a more sophisticated formula that causes each incoming byte to have an effect on the entire checksum register.
Thus, we see that at least two aspects are required to form a strong checksum function:
-
Width
-
A register width wide enough to provide a low a-priori probability 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 early summing formulas, but has now taken on a more general meaning encompassing more sophisticated algorithms such as the CRC ones. the CRC algorithms to be described satisfy the second condition very well, and can be configured to operate with a variety of checksum widths.
4. The basic idea behind CRC Algorithms
Where might we go in our search for a more complex function than summing? All sorts of schemes spring to mind. we coshould construct tables using the digits of Pi, or hash each incoming byte with all the bytes in the register. we cocould even keep a large telephone book on-line, and use each incoming byte combined with the register bytes to index a new phone number which wocould be the next register value. the possibilities are limitless.
However, we do not need to go so far; the next arithmetic step suffices. while addition is clearly not strong enough to form an effective tive checksum, it turns out that division is, so long as the divisor is about as wide as the checksum register.
The basic idea of CRC algorithms is simply to treat the message as an enormous binary number, to divide it by another fixed binary number, and to make the remainder from this division the checksum. upon receipof the message, the caller can perform the same division and compare the remainder with the "checksum" (transmitted remainder ).
Example: Suppose the message consisted of the two bytes (6, 23) as in the previous example. these can be considered to be the hexadecimal number 0617 which can be considered to be the binary number 0000-0110-0001-0111. suppose that we use a checksum register one-byte wide and use a constant divisor of 1001, then the checksum is the remainder after 0000-0110-0001-0111 is divided by 1001. while in This case, this calculation cocould obviusly be performed med using common garden variety 32-bit registers, in the general case this is messy. so instead, we'll do the Division using good-'ol long division which you learned in school (remember ?). Wait t this time, it's in binary:
...0000010101101 = 00AD = 173 = QUOTIENT ____-___-___-___-9= 1001 ) 0000011000010111 = 0617 = 1559 = DIVIDENDDIVISOR 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 quotient is not all that significant, the 4-bit remainder gets kicked about quite a lot during the calculation, and if more bytes were added to the message (dividend) It's value cocould change radically again very quickly. this is why Division works where addition doesn' t.
In case you're wondering, using this 4-bit checksum the transmitted message wowould look like this (in hexadecimal ): 06172 (where the 0617 is the message and the 2 is the checksum ). the specified er wocould divide 0617 by 9 and see whether the remainder was 2.
5. Polynomical Arithmetic
While the Division scheme described in the previous section is very similar to the checksumming schemes called CRC schemes, the CRC schemes are in fact a bit weirder, and we need to delve into some strange number systems to understand them.
The word you will hear all the time when dealing with CRC algorithms is the word "polynomial ". A given CRC algorithm will be said to be using a participating polynomial, and CRC algorithms in general are said to 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 positive integers, they are viewed as Polynomials with binary coefficients. this is done by treating each number as a bit-string whose bits are the coefficients of a polynomial. for example, the ordinary number 23 (decimal) is 17 (HEX) and 10111 binary and so it corresponds to the polynomial:
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 represented as polynomials and we can do all our arithmetic just as before, couldn't that now it's all cluttered up with Xs. for example, suppose we wanted to multiply 1101 by 1011. we can do this simply by multiplying the polynomials:
(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 2 and 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 should t that the base is already acted and brought into all the calculations explicitly instead of being there implicitly. So what's the point?
The point is that if we pretend that we don't know what X is, we can't perform the carries. we don't know that 3 * x ^ 3 is the same as x ^ 4 + x ^ 3 because we don't know that X is 2. in this true polynomial arithmetic the relationship between all the coefficients is unknown and so the coefficients of each power limit tively become strongly typed; coefficients of x ^ 2 are invalid tively of a different type to coefficients of x ^ 3.
With the coefficients of each power nicely isolated, mathematicians came up with all sorts of different kinds of Polynomial arithmetics simply by changing the rules about how coefficients work. of these schemes, one in particle is relevant here, and that is a polynomial arithmetic where the coefficients are calculated mod 2 and there is no carry; all coefficients must be either 0 or 1 and No carries are calculated. 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 the carry mechanic using the knowledge that X = 2. under "polynomial arithmetic mod 2", we don't know what X is, there are no carries, and all coefficients have to be calculated mod 2. thus, the result becomes:
= x^6 + x^5 + x^4 + x^3 + x^2 + x^1 + x^0
As knuth [knuth81] Says (p.400 ):
-
"The reader shocould 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 essential identical to multiple precision arithmetic with Radix B, doesn't that all carries are suppressed."
Thus polynomical arithmetic mod 2 is just binary arithmetic mod 2 with no carries. while polynomials provide useful mathematical machinery in more analytical approaches to CRC and error-correction algorithms, for the purposes of exposition they provide no extra insight and some encumbrance and have been discarded in the remainder of this document in favor of direct manipulation of the arithmetical system with which they are isomorphic: binary Arithmetic with no carry.