Top Banner
Share Error checking Binary encoding is very practical for use in electronic devices such as computers, in which information can be encoded based on whether an electrical signal is present or not. However, this electrical signal may suffer disturbances (such as distortion or noise), especially when data is transported over long distances. For this reason, being able to check to validity of the data is a must for certain uses (including for professionals, banks, industrial uses, and confidential or security-related information) This is why mechanisms exist for ensuring a certain level of data integrity, meaning confirmation for the recipient that the data received is indeed similar to that transmitted. There are two ways to protect data transfers from errors: by installing a more reliable transmission medium, i.e. a physical layer of protection. A conventional connection typically has an error rate between 10 -5 and 10 -7 . or by implementing logical mechanisms for detecting and correcting errors. Most logic-based error control systems are based around adding information (this is called "redundancy") in order to check the validity of the data. This additional information is called a checksum. Error correction Better error detection systems have been perfected, using codes called: Self-correcting codes Self-checking codes Parity check Parity check (sometimes called VRC, for Vertical Redundancy Check or Vertical Redundancy Checking) is one of the simplest checking
77
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Adnet Information

Share

Error checking

Binary encoding is very practical for use in electronic devices such as computers, in which information can be encoded based on whether an electrical signal is present or not.

However, this electrical signal may suffer disturbances (such as distortion or noise), especially when data is transported over long distances. For this reason, being able to check to validity of the data is a must for certain uses (including for professionals, banks, industrial uses, and confidential or security-related information)

This is why mechanisms exist for ensuring a certain level of data integrity, meaning confirmation for the recipient that the data received is indeed similar to that transmitted. There are two ways to protect data transfers from errors:

by installing a more reliable transmission medium, i.e. a physical layer of protection. A conventional connection typically has an error rate between 10-5 and 10-7.

or by implementing logical mechanisms for detecting and correcting errors.

Most logic-based error control systems are based around adding information (this is called "redundancy") in order to check the validity of the data. This additional information is called a checksum.

Error correction

Better error detection systems have been perfected, using codes called:

Self-correcting codes Self-checking codes

Parity check

Parity check (sometimes called VRC, for Vertical Redundancy Check or Vertical Redundancy Checking) is one of the simplest checking mechanisms. It involves adding an additional bit (called a parity bit) to a certain number of bits of data called a code word (generally 7 bits, so as to form a byte when combined with the parity bit) whose value (0 or 1) is such that the total number of 1 bits are even. To be more straightforward, 1 if the number of bits in the code word is odd, 0 otherwise.

Take the following example:

In this example, the number of 1 data bits is even, so the parity bit is set to 0. By contrast, in the example below, the data bits are odd, so the parity bit becomes 1:

Page 2: Adnet Information

Let's pretend that after being transmitted, the lowest-weighted bit of the previous byte (the one on the far right) had fallen victim to interference:

The parity bit, in this case, no longer corresponds to the byte's parity: an error has been detected.

However, if two bits (or an even number of bits) had simulatenously changed as the signal was being sent, no error would have been detected.

As the parity control system can only detect an odd number of errors, it can only detect 50% of all errors. This error-detection mechanism also has the major downside of being unable to correct the errors it finds (the only way to fix it is to request that the erroneous byte be retransmitted)

Longitudinal redundancy check

A longitudinal redundancy check (LRC for short; also called a horizontal redundancy check or cross-parity check) involves checking not the integrity of the data representing a single character, but the bit parity integrity of a group of characters.

Let "HELLO" be the message transmitted, using standard ASCII. Here is the data as it will be transmitted with longitudinal redundancy check codes:

Letter

ASCII Code(7-bit)

Parity bit(LRC)

H 1001000 0E 1000101 1L 1001100 1L 1001100 10 1001111 1VRC 1000010 0

Cyclic Redundancy Check

Page 3: Adnet Information

A cyclic redundancy check (or CRC for short) is a powerful, easy-to-implement data integrity control method. It is the primary method of error detection used in telecommunications.

Concept

Cyclic redundancy checking involves protecting data in blocks, called frames. Each frame is assigned a segment of data, called a control code (occasionally FCS for Frame Check Sequence in the case of a 32-bit sequence, and sometimes erroneously labelled a CRC). The CRC code contains data redundant with the frame, so that errors can be not merely detected, but fixed.

The concept of CRC involves treating binary sequences as binary polynomials, meaning polynomials whose coefficients correspond to the binary sequence. For example, the binary sequence 0110101001 may be represented as a polynomial as shown here:

0*X9 + 1*X8 + 1*X7 + 0*X6 + 1*X5 + 0*X4 + 1*X3 + 0*X2 + 0*X1 + 1*X0

which isX8 + X7 + X5 + X3 + X0

orX8 + X7 + X5 + X3 + 1

In this way, the lowest-weight bit in the sequence (the one furthest to the right) represents degree 0 of the polynomial (X0 = 1), the 4th bit from the right represents degree 3 of the polynomial (X3), and so on. An n-bit sequence, then, forms a polynomial of a maximum degree of n-1. All polynomial expressions are then manipulated using modulo 2.

In this error-detection process, a predefined polynomial (called the generator polynomial and shortened to G(X)) is known to both the sender and the recipient. The sender, to start the error detection mechanism, runs an algorithm on the frame bits in order to generate a CRC, and then transmits these two elements to the recipient. The recipient then performs the same calculation in order to check that the CRC is valid.

Practical application

Let M be the message which corresponds to the frame bits to be sent, and let M(X) be the related polynomial. Let M' be the message transmitted, i.e. the initial message to which an n-bit CRC is to be concatenated. The CRC is such that M'(X)/G(X)=0. The CRC code,

Page 4: Adnet Information

therefore, is equal to the remainder of the polynomial division of M(X) (to which n nul bits, corresponding to the length of the CRC, had previously been appended) over G(X).

For example: take the message M with the following 16 bits: 1011 0001 0010 1010 (called B1 in hexadecimal). Take G(X) = X3 + 1 (represented in binary by 1001). Given that G(X) has degree 3, the result is to add 4 nul bits to M: 10110001001010100000. The CRC is equal to the remainder of M divided by G :

101100010010101000001001...,..,.,.,.....----...,..,.,.,..... 0100..,..,.,.,..... 0000..,..,.,.,..... ----..,..,.,.,..... 1000.,..,.,.,..... 0000.,..,.,.,..... ----.,..,.,.,..... 1000.,..,.,.,..... 1001,..,.,.,..... ----,..,.,.,.....

1111..,.,.,.....1001..,.,.,.....----..,.,.,..... 1100.,.,.,..... 1001.,.,.,..... ----.,.,.,..... 1101,.,.,..... 1001,.,.,..... ----,.,.,..... 1000.,.,..... 0000.,.,..... ----.,.,..... 10001......

1001,.,.....----,.,.....10000.,..... 1001.,..... ---- 1111,..... 1001,..... ----,..... 1100..... 1001..... ----.....

1100....1001....----.... 1010... 1001... ----... 0110.. 0000.. ----.. 1100. 1001. ----.

10101001

Page 5: Adnet Information

----0011

To create M', concatenate the resulting CRC to the bits of the frame to be transmitted:

M' = 1011000100101010 + 0011M' = 10110001001010100011

Therefore, if the message's recipient divides M' by G, he or she will get a remainder of zero if the transmission took place without any errors:

101100010010101000111001...,..,.,.,...,,----...,..,.,.,...,, 0100..,..,.,.,...,, 0000..,..,.,.,...,, ----..,..,.,.,...,, 1000.,..,.,.,..... 1001.,..,.,.,..... ----.,..,.,.,..... 0010,..,.,.,..... 0000,..,.,.,..... ----,..,.,.,.....

0101..,.,.,.....0000..,.,.,.....----..,.,.,..... 1010.,.,.,..... 1001.,.,.,..... ----.,.,.,..... 0110,.,.,..... 0000,.,.,..... ----,.,.,..... 1101.,.,..... 1001.,.,..... ----.,.,.....

1010,.,.....1001,.,.....----,.,..... 0111.,..... 0000.,..... ---- 1110,..... 1001,..... ----,..... 1111..... 1001..... ----.....

1100....1001....----.... 1010... 1001... ----... 0110.. 0000.. ----,, 1101, 1001, ----,

Page 6: Adnet Information

10011001---- 0

Generator polynomials

The most commonly used generator polynomials are:

CRC-12: X12 + X11 + X3 + X2 + X + 1 CRC-16: X16 + X15 + X2 + 1 CRC CCITT V41: X16 + X12 + X5 + 1

(this code is used in the HDLC procedure.) CRC-32 (Ethernet): = X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 + X8 + X7 + X5 +

X4 + X2 + X + 1 CRC ARPA: X24 + X23+ X17 + X16 + X15 + X13 + X11 + X10 + X9 + X8 + X5 + X3 + 1

Last update on Thursday October 16, 2008 02:43:14 PM by Jeff

The CRC is used to ensure the integrity of packets transferred between two MCUs or between MCU and PC connected through an interface such as UART, SPI, I2C ETC.

Some latest MCUs include hardware generation of CRC for the I2C, USART etc.

What we do here is to implement the CRC by software.

INTRODUCTION

The principle of the CRC is to treat as binary sequences of binary polynomials, that is polynomials whose coefficients correspond to the binary sequence.

The binary sequence 0110101001 can be represented with the following polynomial form:

0*X9 + 1*X8 + 1*X7 + 0*X6 + 1*X5 + 0*X4 + 1*X3 + 0*X2 + 0*X1 + 1*X0 ovveroX8 + X7 + X5 + X3 + X0 ovvero X8 + X7 + X5 + X3 + 1In this way, the bit of weight less of the sequence (the rightmost bit) represents the degree 0 of the polynomial  (X0= 1), the fourth bit from the right represents the degree of the polynomial 3 (X3) ...

A sequence of n bits is therefore a polynomial of maximum degree n-1. All polynomial expressions are subsequently manipulated by modulo 2.

Page 7: Adnet Information

In practice it is assumed that the polynomial used to generate the CRC is known to both the transmitter and receiver.

Generator polynomial G (n + 1 bit) The Message (M) to be transmitted can be formed from any sequence of bits The CRC will be given by the division of M / G (see explanation below) The message to be transmitted, that contains also the CRC, will be M' which is given by

M with the CRC appended to the end of the message The receiver calculates the CRC on the received message M' (M' = M + CRC) and will

get rest as 0 (zero) if the transfer of data occurred without error.

Generator Polynomial G normally as you choose a prime number that begins and ends with 1, some examples are:1001 - 11101 - 1100000001111 (CRC12) - 11000000000000101 (CRC16)

APPLICATION

Let M be the message to be transmitted, the value is: 1010 0011 1010 1100It is assumed that G is 11010We call M' the message with the CRCThe CRC isM / G. The CRCcode is the result of the division M / Gwhere to M are attached nbits null (0) corresponding to the degree of G.We assume that G = 11010this means that its grade is 4; this means G(bit)=4so we attach 4null bits (0) to M.Now Mis:

Page 8: Adnet Information

M = 1010 0011 1010 11000000. Below is an example on how to calculate the CRC.

1010 0011 1010 1100 00001101 0||| since the leftmost bit is 1 we do the subtraction0111 0||| here's the result after the XOR111 00|| bring down the next digit, an since the leftmost bit is 1 we again subtract110 10|| perform the subtraction 001 10|| here's the result after the XOR01 101| bring down the next digit, and since the leftmost bit is 0 not do the subtraction and bring down another bit 1 1011 as the leftmost bit is 1 we again subtract 1 10100 0001 here's the result after the XOR

zzzzz

Repeating these steps till the end, we will get:xxxx

1010 0011 1010 1100 00001101 00111 00 110 10 001 101 01 1011 1 1010 0 0001 1 0001 10 001 101 01 1010 1 1010 0 0000 1 0000 11 000 110 00 1100 0 1100 0 1101 0 0001 00 001 000 01 0000 1 1010 0 1010 == CRC

To create M' it is sufficient to concatenate the CRC obtained to the M (message) to be transmitted:M' = 1010 0011 1010 1100 + 1010M' = 1010 0011 1010 1100 1010

In general, the algorithm used can be represented as below.Input there is: M' = M + G(bit)The loop is repeated until the last bit of M'

Page 9: Adnet Information

0 == CRC che essendo zero

If the receiver makes the division of M' with G and gets 0 (zero) it means that there were no errors during transmission.

Below there is an example where the CRC is concatenated to message during Tx and Rx that receive the message and recalculate the CRC (must be 0).

Page 10: Adnet Information

Main Polynomials

CRC-12 : X12 + X11 + X3 + X2 + X + 1      1100000001111

CRC-16 : X16 + X15 + X2 + 1      11000000000000101

CRC CCITT V41 : X16 + X12 + X5 + 1  (This code is primarily used in the HDLC)      10001000000100001

CRC-32 (Ethernet) : = X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X + 1

CRC ARPA : X24 + X23+ X17 + X16 + X15 + X13 + X11 + X10 + X9 + X8 + X5 + X3 + 1 SDLC: X16 + X12 + X5 + 1

Page 11: Adnet Information

MCU Implementation

There are two different techniques for implementing a CRC in software.

Loop driven implementation Table driven implementation

Loop driven implementation works like the calculation showed in Figure 1 (for 8bit MCU). Data is entered into shift register and shifted to the left in sequence one at a time.

If one pops out at the MSb, the content is XORed with the polynomial. In the other case, the registers are shifted by one position to the left.

Table driven implementationAnother method to calculate a CRC is to use precalculated values and XOR them to the data received.The idea behind a table driven CRC implementation is that instead of calculating the CRC bit by bit, precomputed bytes are XORed to the data.The advantage of the table driven implementation is that it is faster than theloop driven solution. The drawback is that it consumes more program memory because of the size of the look-up

Page 12: Adnet Information

table.The CRC at the table driven implementation is generated by reading a precomputed value out of a table and XOR.

Comparation Table for 8bit MCU

Loop driven implementation

/* bit by bit * The width of the CRC calculation and result. * Modify the typedef for a 16 or 32-bit CRC standard. */typedef uint8_t crc;

#define WIDTH (8 * sizeof(crc))#define TOPBIT (1 << (WIDTH - 1))

crccrcSlow(uint8_t const message[], int nBytes){ crc remainder = 0;

/* * Perform modulo-2 division, a byte at a time. */ for (int byte = 0; byte < nBytes; ++byte) { /* * Bring the next byte into the remainder. */ remainder ^= (message[byte] << (WIDTH - 8));

/* * Perform modulo-2 division, a bit at a time. */ for (uint8_t bit = 8; bit > 0; --bit) { /* * Try to divide the current data bit. */ if (remainder & TOPBIT) { remainder = (remainder << 1) ^ POLYNOMIAL;

Page 13: Adnet Information

} else { remainder = (remainder << 1); } } }

/* * The final remainder is the CRC result. */ return (remainder);

} /* crcSlow() */

Table driven implementation

TABLE precalculation

crc crcTable[256];

voidcrcInit(void){ crc remainder;

/* * Compute the remainder of each possible dividend. */ for (int dividend = 0; dividend < 256; ++dividend) { /* * Start with the dividend followed by zeros. */ remainder = dividend << (WIDTH - 8);

/* * Perform modulo-2 division, a bit at a time. */ for (uint8_t bit = 8; bit > 0; --bit) { /* * Try to divide the current data bit. */ if (remainder & TOPBIT) { remainder = (remainder << 1) ^ POLYNOMIAL; } else { remainder = (remainder << 1); } }

/* * Store the result into the table. */ crcTable[dividend] = remainder; }

Page 14: Adnet Information

} /* crcInit() */

Table driven implementation

crccrcFast(uint8_t const message[], int nBytes){ uint8_t data; crc remainder = 0;

/* * Divide the message by the polynomial, a byte at a time. */ for (int byte = 0; byte < nBytes; ++byte) { data = message[byte] ^ (remainder >> (WIDTH - 8)); remainder = crcTable[data] ^ (remainder << 8); }

/* * The final remainder is the CRC. */ return (remainder);

} /* crcFast() */

Free source code in C

The example Loop driven andTable driven ready to use on Windows developed by Dev-C++ is here.The Dev-C++ is free and it is possible to get it here, if you need to use my version of Dev-C++ click here.

The original source code for these CRC computations is placed into the public domain and is available in electronic form at http://www.netrino.com/code/crc.zip

Other examples to be tested:

// Programma che calcola il CRC di una sequenza di caratteri// immessi da tastiera, terminati con EOF

Page 15: Adnet Information

#include <stdio.h>

#define PG 0x11021 /* Polinomio generatre */

int crc(int oldcrc, unsigned char toadd); /* Aggiunge toadd al CRC calcolato */

main(){int resto=0; // CRCint c; // Carattere lettoint i = 0; // Contatore dei caratteri

printf("Inserisci una sequenza di caratteri: "); while((c=getchar())!=EOF) { resto=crc(resto,c); // Agginge il carattere letto al CRC dei precedenti i++; // Conta i caratteri letti } resto=crc(resto,0); // Agginge al CRC i primi otto zeri resto=crc(resto,0); // Agginge al CRC i secondi otto zeri in fondo

printf("\nLetti %d caratteri, CRC calcolato: %x\n", i, resto); }

/* Aggiunge i bit del codice oldcrc al dividendo, per * calcolare il nuovo CRC */ int crc(int oldcrc, unsigned char toadd){int i; // Indice del bit

// I bit del carattere vanno trattati dal piu' significativo al meno for(i=0;i<8;i++) // Per ogni bit del byte { oldcrc= (oldcrc<<1) | (toadd>>7); // Aggiunge il bit piu' significativo // del codice in fondo al CRC, // spostando a sinistra i bit del CRC toadd <<= 1; // Toglie il bit gestito dal codice if((oldcrc & 0x10000) != 0) // Se il divisore ci sta' (alla sua maniera) { oldcrc=oldcrc^PG; // Allora lo toglie (sottrazione senza riporti, // quindi XOR } } return oldcrc; // Restituisce il CRC ricalcolato}

CRC16 Calculation Algorithm

Polynomial: x16 + x12 + x5 + 1 Start Value: 0xFFFF

Page 16: Adnet Information

CRC_POLYNOM = 0x8408;CRC_PRESET = 0xFFFF;

C-Example:

unsigned internal CRC = CRC_PRESET;for (i = 0; i < cnt; i++) /* cnt = number of protocol bytes without CRC */{    crc ^= DATA[i];    for (j = 0; j < 8; j++)    {        if (crc & 0x0001)            crc = (crc >> 1) ^ CRC_POLYNOM;        else            crc = (crc >> 1);    }}

A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS=================================================="Everything you wanted to know about CRC algorithms, but were afraidto ask for fear that errors in your understanding might be detected."

Version : 3.Date : 19 August 1993.Author : Ross N. Williams.Net : [email protected] : ftp.adelaide.edu.au/pub/rocksoft/crc_v3.txtCompany : 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. However, permission is granted to make and distribute verbatim copies of this document provided that this information block and copyright notice is included. Also, the C code modules included in this document are fully public domain.Thanks : Thanks to Jean-loup Gailly ([email protected]) and Mark Adler ([email protected]) who both proof read this document and picked out lots of nits as well as some big fat bugs.

Table of Contents----------------- Abstract 1. Introduction: Error Detection 2. The Need For Complexity 3. The Basic Idea Behind CRC Algorithms 4. Polynomical Arithmetic 5. Binary Arithmetic with No Carries 6. A Fully Worked Example 7. Choosing A Poly 8. A Straightforward CRC Implementation 9. A Table-Driven Implementation10. A Slightly Mangled Table-Driven Implementation

Page 17: Adnet Information

11. "Reflected" Table-Driven Implementations12. "Reversed" Polys13. Initial and Final Values14. Defining Algorithms Absolutely15. A Parameterized Model For CRC Algorithms16. A Catalog of Parameter Sets for Standards17. An Implementation of the Model Algorithm18. Roll Your Own Table-Driven Implementation19. Generating A Lookup Table20. Summary21. Corrections A. Glossary B. References C. References I Have Detected But Haven't Yet Sighted

Abstract--------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.

1. Introduction: Error Detection--------------------------------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.

Page 18: Adnet Information

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>

2. The Need For Complexity--------------------------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-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 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.

Page 19: Adnet Information

3. The Basic Idea Behind CRC Algorithms---------------------------------------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 youlearnt in school (remember?). Except 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.,,,

Page 20: Adnet Information

----.,,, 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.

4. Polynomical Arithmetic-------------------------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:

Page 21: Adnet Information

(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, for

Page 22: Adnet Information

the 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.

5. Binary Arithmetic with No Carries------------------------------------Having dispensed with polynomials, we can focus on the real arithmeticissue, which is that all the arithmetic performed during CRCcalculations is performed in binary with no carries. Often this iscalled polynomial arithmetic, but as I have declared the rest of thisdocument a polynomial free zone, we'll have to call it CRC arithmeticinstead. As this arithmetic is a key part of CRC calculations, we'dbetter get used to it. Here we go:

Adding two numbers in CRC arithmetic is the same as adding numbers inordinary binary arithmetic except there is no carry. This means thateach pair of corresponding bits determine the corresponding output bitwithout reference to any other bit positions. For example:

10011011 +11001010 -------- 01010001 --------

There are only four cases for each bit position:

0+0=0 0+1=1 1+0=1 1+1=0 (no carry)

Subtraction is identical:

10011011 -11001010 -------- 01010001 --------

with

0-0=0 0-1=1 (wraparound) 1-0=1 1-1=0

In fact, both addition and subtraction in CRC arithmetic is equivalentto the XOR operation, and the XOR operation is its own inverse. Thiseffectively reduces the operations of the first level of power(addition, subtraction) to a single operation that is its own inverse.This is a very convenient property of the arithmetic.

By collapsing of addition and subtraction, the arithmetic discards anynotion of magnitude beyond the power of its highest one bit. While itseems clear that 1010 is greater than 10, it is no longer the casethat 1010 can be considered to be greater than 1001. To see this, notethat you can get from 1010 to 1001 by both adding and subtracting thesame quantity:

Page 23: Adnet Information

1010 = 1010 + 0011 1010 = 1010 - 0011

This makes nonsense of any notion of order.

Having defined addition, we can move to multiplication and division.Multiplication is absolutely straightforward, being the sum of thefirst number, shifted in accordance with the second number.

1101 x 1011 ---- 1101 1101. 0000.. 1101... ------- 1111111 Note: The sum uses CRC addition -------

Division is a little messier as we need to know when "a number goesinto another number". To do this, we invoke the weak definition ofmagnitude defined earlier: that X is greater than or equal to Y iffthe position of the highest 1 bit of X is the same or greater than theposition of the highest 1 bit of Y. Here's a fully worked division(nicked from [Tanenbaum81]).

1100001010 _______________10011 ) 11010110110000 10011,,.,,.... -----,,.,,.... 10011,.,,.... 10011,.,,.... -----,.,,.... 00001.,,.... 00000.,,.... -----.,,.... 00010,,.... 00000,,.... -----,,.... 00101,.... 00000,.... -----,.... 01011.... 00000.... -----.... 10110... 10011... -----... 01010.. 00000.. -----.. 10100. 10011. -----. 01110 00000 ----- 1110 = Remainder

Page 24: Adnet Information

That's really it. Before proceeding further, however, it's worth ourwhile playing with this arithmetic a bit to get used to it.

We've already played with addition and subtraction, noticing that theyare the same thing. Here, though, we should note that in thisarithmetic A+0=A and A-0=A. This obvious property is very usefullater.

In dealing with CRC multiplication and division, it's worth getting afeel for the concepts of MULTIPLE and DIVISIBLE.

If a number A is a multiple of B then what this means in CRCarithmetic is that it is possible to construct A from zero by XORingin various shifts of B. For example, if A was 0111010110 and B was 11,we could construct A from B as follows:

0111010110 = .......11. + ....11.... + ...11..... .11.......

However, if A is 0111010111, it is not possible to construct it out ofvarious shifts of B (can you see why? - see later) so it is said to benot divisible by B in CRC arithmetic.

Thus we see that CRC arithmetic is primarily about XORing particularvalues at various shifting offsets.

6. A Fully Worked Example-------------------------Having defined CRC arithmetic, we can now frame a CRC calculation assimply a division, because that's all it is! This section fills in thedetails and gives an example.

To perform a CRC calculation, we need to choose a divisor. In mathsmarketing speak the divisor is called the "generator polynomial" orsimply the "polynomial", and is a key parameter of any CRC algorithm.It would probably be more friendly to call the divisor something else,but the poly talk is so deeply ingrained in the field that it wouldnow be confusing to avoid it. As a compromise, we will refer to theCRC polynomial as the "poly". Just think of this number as a sort ofparrot. "Hello poly!"

You can choose any poly and come up with a CRC algorithm. However,some polys are better than others, and so it is wise to stick with thetried an tested ones. A later section addresses this issue.

The width (position of the highest 1 bit) of the poly is veryimportant as it dominates the whole calculation. Typically, widths of16 or 32 are chosen so as to simplify implementation on moderncomputers. The width of a poly is the actual bit position of thehighest bit. For example, the width of 10011 is 4, not 5. For thepurposes of example, we will chose a poly of 10011 (of width W of 4).

Having chosen a poly, we can proceed with the calculation. This issimply a division (in CRC arithmetic) of the message by the poly. Theonly trick is that W zero bits are appended to the message before theCRC is calculated. Thus we have:

Page 25: Adnet Information

Original message : 1101011011 Poly : 10011 Message after appending W zeros : 11010110110000

Now we simply divide the augmented message by the poly using CRCarithmetic. This is the same division as before:

1100001010 = Quotient (nobody cares about the quotient) _______________10011 ) 11010110110000 = Augmented message (1101011011 + 0000)=Poly 10011,,.,,.... -----,,.,,.... 10011,.,,.... 10011,.,,.... -----,.,,.... 00001.,,.... 00000.,,.... -----.,,.... 00010,,.... 00000,,.... -----,,.... 00101,.... 00000,.... -----,.... 01011.... 00000.... -----.... 10110... 10011... -----... 01010.. 00000.. -----.. 10100. 10011. -----. 01110 00000 ----- 1110 = Remainder = THE CHECKSUM!!!!

The division yields a quotient, which we throw away, and a remainder,which is the calculated checksum. This ends the calculation.

Usually, the checksum is then appended to the message and the resulttransmitted. In this case the transmission would be: 11010110111110.

At the other end, the receiver can do one of two things:

a. Separate the message and checksum. Calculate the checksum for the message (after appending W zeros) and compare the two checksums.

b. Checksum the whole lot (without appending zeros) and see if it comes out as zero!

These two options are equivalent. However, in the next section, wewill be assuming option b because it is marginally mathematicallycleaner.

Page 26: Adnet Information

A summary of the operation of the class of CRC algorithms:

1. Choose a width W, and a poly G (of width W). 2. Append W zero bits to the message. Call this M'. 3. Divide M' by G using CRC arithmetic. The remainder is the checksum.

That's all there is to it.

7. Choosing A Poly------------------Choosing a poly is somewhat of a black art and the reader is referredto [Tanenbaum81] (p.130-132) which has a very clear discussion of thisissue. This section merely aims to put the fear of death into anyonewho so much as toys with the idea of making up their own poly. If youdon't care about why one poly might be better than another and justwant to find out about high-speed implementations, choose one of thearithmetically sound polys listed at the end of this section and skipto the next section.

First note that the transmitted message T is a multiple of the poly.To see this, note that 1) the last W bits of T is the remainder afterdividing the augmented (by zeros remember) message by the poly, and 2)addition is the same as subtraction so adding the remainder pushes thevalue up to the next multiple. Now note that if the transmittedmessage is corrupted in transmission that we will receive T+E where Eis an error vector (and + is CRC addition (i.e. XOR)). Upon receipt ofthis message, the receiver divides T+E by G. As T mod G is 0, (T+E)mod G = E mod G. Thus, the capacity of the poly we choose to catchparticular kinds of errors will be determined by the set of multiplesof G, for any corruption E that is a multiple of G will be undetected.Our task then is to find classes of G whose multiples look as littlelike the kind of line noise (that will be creating the corruptions) aspossible. So let's examine the kinds of line noise we can expect.

SINGLE BIT ERRORS: A single bit error means E=1000...0000. We canensure that this class of error is always detected by making sure thatG has at least two bits set to 1. Any multiple of G will beconstructed using shifting and adding and it is impossible toconstruct a value with a single bit by shifting an adding a singlevalue with more than one bit set, as the two end bits will alwayspersist.

TWO-BIT ERRORS: To detect all errors of the form 100...000100...000(i.e. E contains two 1 bits) choose a G that does not have multiplesthat are 11, 101, 1001, 10001, 100001, etc. It is not clear to me howone goes about doing this (I don't have the pure maths background),but Tanenbaum assures us that such G do exist, and cites G with 1 bits(15,14,1) turned on as an example of one G that won't divide anythingless than 1...1 where ... is 32767 zeros.

ERRORS WITH AN ODD NUMBER OF BITS: We can catch all corruptions whereE has an odd number of bits by choosing a G that has an even number ofbits. To see this, note that 1) CRC multiplication is simply XORing aconstant value into a register at various offsets, 2) XORing is simplya bit-flip operation, and 3) if you XOR a value with an even number ofbits into a register, the oddness of the number of 1 bits in theregister remains invariant. Example: Starting with E=111, attempt toflip all three bits to zero by the repeated application of XORing in11 at one of the two offsets (i.e. "E=E XOR 011" and "E=E XOR 110")This is nearly isomorphic to the "glass tumblers" party puzzle whereyou challenge someone to flip three tumblers by the repeated

Page 27: Adnet Information

application of the operation of flipping any two. Most of the popularCRC polys contain an even number of 1 bits. (Note: Tanenbaum statesmore specifically that all errors with an odd number of bits can becaught by making G a multiple of 11).

BURST ERRORS: A burst error looks like E=000...000111...11110000...00.That is, E consists of all zeros except for a run of 1s somewhereinside. This can be recast as E=(10000...00)(1111111...111) wherethere are z zeros in the LEFT part and n ones in the RIGHT part. Tocatch errors of this kind, we simply set the lowest bit of G to 1.Doing this ensures that LEFT cannot be a factor of G. Then, so long asG is wider than RIGHT, the error will be detected. See Tanenbaum for aclearer explanation of this; I'm a little fuzzy on this one. Note:Tanenbaum asserts that the probability of a burst of length greaterthan W getting through is (0.5)^W.

That concludes the section on the fine art of selecting polys.

Some popular polys are:16 bits: (16,12,5,0) [X25 standard] (16,15,2,0) ["CRC-16"]32 bits: (32,26,23,22,16,12,11,10,8,7,5,4,2,1,0) [Ethernet]

8. A Straightforward CRC Implementation---------------------------------------That's the end of the theory; now we turn to implementations. To startwith, we examine an absolutely straight-down-the-middle boringstraightforward low-speed implementation that doesn't use any speedtricks at all. We'll then transform that program progessively until weend up with the compact table-driven code we all know and love andwhich some of us would like to understand.

To implement a CRC algorithm all we have to do is implement CRCdivision. There are two reasons why we cannot simply use the divideinstruction of whatever machine we are on. The first is that we haveto do the divide in CRC arithmetic. The second is that the dividendmight be ten megabytes long, and todays processors do not haveregisters that big.

So to implement CRC division, we have to feed the message through adivision register. At this point, we have to be absolutely preciseabout the message data. In all the following examples the message willbe considered to be a stream of bytes (each of 8 bits) with bit 7 ofeach byte being considered to be the most significant bit (MSB). Thebit stream formed from these bytes will be the bit stream with the MSB(bit 7) of the first byte first, going down to bit 0 of the firstbyte, and then the MSB of the second byte and so on.

With this in mind, we can sketch an implementation of the CRCdivision. For the purposes of example, consider a poly with W=4 andthe poly=10111. Then, the perform the division, we need to use a 4-bitregister:

3 2 1 0 Bits +---+---+---+---+ Pop! <-- | | | | | <----- Augmented message +---+---+---+---+

1 0 1 1 1 = The Poly

Page 28: Adnet Information

(Reminder: The augmented message is the message followed by W zero bits.)

To perform the division perform the following:

Load the register with zero bits. Augment the message by appending W zero bits to the end of it. While (more message bits) Begin Shift the register left by one bit, reading the next bit of the augmented message into register bit position 0. If (a 1 bit popped out of the register during step 3) Register = Register XOR Poly. End The register now contains the remainder.

(Note: In practice, the IF condition can be tested by testing the top bit of R before performing the shift.)

We will call this algorithm "SIMPLE".

This might look a bit messy, but all we are really doing is"subtracting" various powers (i.e. shiftings) of the poly from themessage until there is nothing left but the remainder. Study themanual examples of long division if you don't understand this.

It should be clear that the above algorithm will work for any width W.

9. A Table-Driven Implementation--------------------------------The SIMPLE algorithm above is a good starting point because itcorresponds directly to the theory presented so far, and because it isso SIMPLE. However, because it operates at the bit level, it is ratherawkward to code (even in C), and inefficient to execute (it has toloop once for each bit). To speed it up, we need to find a way toenable the algorithm to process the message in units larger than onebit. Candidate quantities are nibbles (4 bits), bytes (8 bits), words(16 bits) and longwords (32 bits) and higher if we can achieve it. Ofthese, 4 bits is best avoided because it does not correspond to a byteboundary. At the very least, any speedup should allow us to operate atbyte boundaries, and in fact most of the table driven algorithmsoperate a byte at a time.

For the purposes of discussion, let us switch from a 4-bit poly to a32-bit one. Our register looks much the same, except the boxesrepresent bytes instead of bits, and the Poly is 33 bits (one implicit1 bit at the top and 32 "active" bits) (W=32).

3 2 1 0 Bytes +----+----+----+----+ Pop! <-- | | | | | <----- Augmented message +----+----+----+----+

1<------32 bits------>

The SIMPLE algorithm is still applicable. Let us examine what it does.Imagine that the SIMPLE algorithm is in full swing and consider thetop 8 bits of the 32-bit register (byte 3) to have the values:

t7 t6 t5 t4 t3 t2 t1 t0

Page 29: Adnet Information

In the next iteration of SIMPLE, t7 will determine whether the Polywill be XORed into the entire register. If t7=1, this will happen,otherwise it will not. Suppose that the top 8 bits of the poly are g7g6.. g0, then after the next iteration, the top byte will be:

t6 t5 t4 t3 t2 t1 t0 ??+ t7 * (g7 g6 g5 g4 g3 g2 g1 g0) [Reminder: + is XOR]

The NEW top bit (that will control what happens in the next iteration)now has the value t6 + t7*g7. The important thing to notice here isthat from an informational point of view, all the information requiredto calculate the NEW top bit was present in the top TWO bits of theoriginal top byte. Similarly, the NEXT top bit can be calculated inadvance SOLELY from the top THREE bits t7, t6, and t5. In fact, ingeneral, the value of the top bit in the register in k iterations canbe calculated from the top k bits of the register. Let us take thisfor granted for a moment.

Consider for a moment that we use the top 8 bits of the register tocalculate the value of the top bit of the register during the next 8iterations. Suppose that we drive the next 8 iterations using thecalculated values (which we could perhaps store in a single byteregister and shift out to pick off each bit). Then we note threethings:

* The top byte of the register now doesn't matter. No matter how many times and at what offset the poly is XORed to the top 8 bits, they will all be shifted out the right hand side during the next 8 iterations anyway.

* The remaining bits will be shifted left one position and the rightmost byte of the register will be shifted in the next byte

AND

* While all this is going on, the register will be subjected to a series of XOR's in accordance with the bits of the pre-calculated control byte.

Now consider the effect of XORing in a constant value at variousoffsets to a register. For example:

0100010 Register ...0110 XOR this ..0110. XOR this 0110... XOR this ------- 0011000 -------

The point of this is that you can XOR constant values into a registerto your heart's delight, and in the end, there will exist a valuewhich when XORed in with the original register will have the sameeffect as all the other XORs.

Perhaps you can see the solution now. Putting all the pieces togetherwe have an algorithm that goes like this:

While (augmented message is not exhausted) Begin

Page 30: Adnet Information

Examine the top byte of the register Calculate the control byte from the top byte of the register Sum all the Polys at various offsets that are to be XORed into the register in accordance with the control byte Shift the register left by one byte, reading a new message byte into the rightmost byte of the register XOR the summed polys to the register End

As it stands this is not much better than the SIMPLE algorithm.However, it turns out that most of the calculation can be precomputedand assembled into a table. As a result, the above algorithm can bereduced to:

While (augmented message is not exhaused) Begin Top = top_byte(Register); Register = (Register << 24) | next_augmessage_byte; Register = Register XOR precomputed_table[Top]; End

There! If you understand this, you've grasped the main idea oftable-driven CRC algorithms. The above is a very efficient algorithmrequiring just a shift, and OR, an XOR, and a table lookup per byte.Graphically, it looks like this:

3 2 1 0 Bytes +----+----+----+----+ +-----<| | | | | <----- Augmented message | +----+----+----+----+ | ^ | | | XOR | | | 0+----+----+----+----+ Algorithm v +----+----+----+----+ --------- | +----+----+----+----+ 1. Shift the register left by | +----+----+----+----+ one byte, reading in a new | +----+----+----+----+ message byte. | +----+----+----+----+ 2. Use the top byte just rotated | +----+----+----+----+ out of the register to index +----->+----+----+----+----+ the table of 256 32-bit values. +----+----+----+----+ 3. XOR the table value into the +----+----+----+----+ register. +----+----+----+----+ 4. Goto 1 iff more augmented +----+----+----+----+ message bytes. 255+----+----+----+----+

In C, the algorithm main loop looks like this:

r=0; while (len--) { byte t = (r >> 24) & 0xFF; r = (r << 8) | *p++; r^=table[t]; }

Page 31: Adnet Information

where len is the length of the augmented message in bytes, p points tothe augmented message, r is the register, t is a temporary, and tableis the computed table. This code can be made even more unreadable asfollows:

r=0; while (len--) r = ((r << 8) | *p++) ^ t[(r >> 24) & 0xFF];

This is a very clean, efficient loop, although not a very obvious oneto the casual observer not versed in CRC theory. We will call this theTABLE algorithm.

10. A Slightly Mangled Table-Driven Implementation--------------------------------------------------Despite the terse beauty of the line

r=0; while (len--) r = ((r << 8) | *p++) ^ t[(r >> 24) & 0xFF];

those optimizing hackers couldn't leave it alone. The trouble, yousee, is that this loop operates upon the AUGMENTED message and inorder to use this code, you have to append W/8 zero bytes to the endof the message before pointing p at it. Depending on the run-timeenvironment, this may or may not be a problem; if the block of datawas handed to us by some other code, it could be a BIG problem. Onealternative is simply to append the following line after the aboveloop, once for each zero byte:

for (i=0; i<W/4; i++) r = (r << 8) ^ t[(r >> 24) & 0xFF];

This looks like a sane enough solution to me. However, at the furtherexpense of clarity (which, you must admit, is already a pretty scarecommodity in this code) we can reorganize this small loop further soas to avoid the need to either augment the message with zero bytes, orto explicitly process zero bytes at the end as above. To explain theoptimization, we return to the processing diagram given earlier.

3 2 1 0 Bytes +----+----+----+----+ +-----<| | | | | <----- Augmented message | +----+----+----+----+ | ^ | | | XOR | | | 0+----+----+----+----+ Algorithm v +----+----+----+----+ --------- | +----+----+----+----+ 1. Shift the register left by | +----+----+----+----+ one byte, reading in a new | +----+----+----+----+ message byte. | +----+----+----+----+ 2. Use the top byte just rotated | +----+----+----+----+ out of the register to index +----->+----+----+----+----+ the table of 256 32-bit values. +----+----+----+----+ 3. XOR the table value into the +----+----+----+----+ register. +----+----+----+----+ 4. Goto 1 iff more augmented +----+----+----+----+ message bytes. 255+----+----+----+----+

Now, note the following facts:

Page 32: Adnet Information

TAIL: The W/4 augmented zero bytes that appear at the end of the message will be pushed into the register from the right as all the other bytes are, but their values (0) will have no effect whatsoever on the register because 1) XORing with zero does not change the target byte, and 2) the four bytes are never propagated out the left side of the register where their zeroness might have some sort of influence. Thus, the sole function of the W/4 augmented zero bytes is to drive the calculation for another W/4 byte cycles so that the end of the REAL data passes all the way through the register.

HEAD: If the initial value of the register is zero, the first four iterations of the loop will have the sole effect of shifting in the first four bytes of the message from the right. This is because the first 32 control bits are all zero and so nothing is XORed into the register. Even if the initial value is not zero, the first 4 byte iterations of the algorithm will have the sole effect of shifting the first 4 bytes of the message into the register and then XORing them with some constant value (that is a function of the initial value of the register).

These facts, combined with the XOR property

(A xor B) xor C = A xor (B xor C)

mean that message bytes need not actually travel through the W/4 bytesof the register. Instead, they can be XORed into the top byte justbefore it is used to index the lookup table. This leads to thefollowing modified version of the algorithm.

+-----<Message (non augmented) | v 3 2 1 0 Bytes | +----+----+----+----+ XOR----<| | | | | | +----+----+----+----+ | ^ | | | XOR | | | 0+----+----+----+----+ Algorithm v +----+----+----+----+ --------- | +----+----+----+----+ 1. Shift the register left by | +----+----+----+----+ one byte, reading in a new | +----+----+----+----+ message byte. | +----+----+----+----+ 2. XOR the top byte just rotated | +----+----+----+----+ out of the register with the +----->+----+----+----+----+ next message byte to yield an +----+----+----+----+ index into the table ([0,255]). +----+----+----+----+ 3. XOR the table value into the +----+----+----+----+ register. +----+----+----+----+ 4. Goto 1 iff more augmented 255+----+----+----+----+ message bytes.

Note: The initial register value for this algorithm must be the

Page 33: Adnet Information

initial value of the register for the previous algorithm fed throughthe table four times. Note: The table is such that if the previousalgorithm used 0, the new algorithm will too.

This is an IDENTICAL algorithm and will yield IDENTICAL results. The Ccode looks something like this:

r=0; while (len--) r = (r<<8) ^ t[(r >> 24) ^ *p++];

and THIS is the code that you are likely to find inside currenttable-driven CRC implementations. Some FF masks might have to be ANDedin here and there for portability's sake, but basically, the aboveloop is IT. We will call this the DIRECT TABLE ALGORITHM.

During the process of trying to understand all this stuff, I managedto derive the SIMPLE algorithm and the table-driven version derivedfrom that. However, when I compared my code with the code found inreal-implementations, I was totally bamboozled as to why the byteswere being XORed in at the wrong end of the register! It took quite awhile before I figured out that theirs and my algorithms were actuallythe same. Part of why I am writing this document is that, while thelink between division and my earlier table-driven code is vaguelyapparent, any such link is fairly well erased when you start pumpingbytes in at the "wrong end" of the register. It looks all wrong!

If you've got this far, you not only understand the theory, thepractice, the optimized practice, but you also understand the realcode you are likely to run into. Could get any more complicated? Yesit can.

11. "Reflected" Table-Driven Implementations--------------------------------------------Despite the fact that the above code is probably optimized about asmuch as it could be, this did not stop some enterprising individualsfrom making things even more complicated. To understand how thishappened, we have to enter the world of hardware.

DEFINITION: A value/register is reflected if it's bits are swappedaround its centre. For example: 0101 is the 4-bit reflection of 1010.0011 is the reflection of 1100.0111-0101-1010-1111-0010-0101-1011-1100 is the reflection of0011-1101-1010-0100-1111-0101-1010-1110.

Turns out that UARTs (those handy little chips that perform serial IO)are in the habit of transmitting each byte with the least significantbit (bit 0) first and the most significant bit (bit 7) last (i.e.reflected). An effect of this convention is that hardware engineersconstructing hardware CRC calculators that operate at the bit leveltook to calculating CRCs of bytes streams with each of the bytesreflected within itself. The bytes are processed in the same order,but the bits in each byte are swapped; bit 0 is now bit 7, bit 1 isnow bit 6, and so on. Now this wouldn't matter much if this conventionwas restricted to hardware land. However it seems that at some stagesome of these CRC values were presented at the software level andsomeone had to write some code that would interoperate with thehardware CRC calculation.

In this situation, a normal sane software engineer would simplyreflect each byte before processing it. However, it would seem thatnormal sane software engineers were thin on the ground when this early

Page 34: Adnet Information

ground was being broken, because instead of reflecting the bytes,whoever was responsible held down the byte and reflected the world,leading to the following "reflected" algorithm which is identical tothe previous one except that everything is reflected except the inputbytes.

Message (non augmented) >-----+ | Bytes 0 1 2 3 v +----+----+----+----+ | | | | | |>----XOR +----+----+----+----+ | ^ | | | XOR | | | +----+----+----+----+0 | +----+----+----+----+ v +----+----+----+----+ | +----+----+----+----+ | +----+----+----+----+ | +----+----+----+----+ | +----+----+----+----+ | +----+----+----+----+<-----+ +----+----+----+----+ +----+----+----+----+ +----+----+----+----+ +----+----+----+----+ +----+----+----+----+255

Notes:

* The table is identical to the one in the previous algorithm except that each entry has been reflected.

* The initial value of the register is the same as in the previous algorithm except that it has been reflected.

* The bytes of the message are processed in the same order as before (i.e. the message itself is not reflected).

* The message bytes themselves don't need to be explicitly reflected, because everything else has been!

At the end of execution, the register contains the reflection of thefinal CRC value (remainder). Actually, I'm being rather hard onwhoever cooked this up because it seems that hardware implementationsof the CRC algorithm used the reflected checksum value and soproducing a reflected CRC was just right. In fact reflecting the worldwas probably a good engineering solution - if a confusing one.

We will call this the REFLECTED algorithm.

Whether or not it made sense at the time, the effect of havingreflected algorithms kicking around the world's FTP sites is thatabout half the CRC implementations one runs into are reflected and theother half not. It's really terribly confusing. In particular, itwould seem to me that the casual reader who runs into a reflected,table-driven implementation with the bytes "fed in the wrong end"would have Buckley's chance of ever connecting the code to the concept

Page 35: Adnet Information

of binary mod 2 division.

It couldn't get any more confusing could it? Yes it could.

12. "Reversed" Polys--------------------As if reflected implementations weren't enough, there is anotherconcept kicking around which makes the situation bizaarly confusing.The concept is reversed Polys.

It turns out that the reflection of good polys tend to be good polystoo! That is, if G=11101 is a good poly value, then 10111 will be aswell. As a consequence, it seems that every time an organization (suchas CCITT) standardizes on a particularly good poly ("polynomial"),those in the real world can't leave the poly's reflection aloneeither. They just HAVE to use it. As a result, the set of "standard"poly's has a corresponding set of reflections, which are also in use.To avoid confusion, we will call these the "reversed" polys.

X25 standard: 1-0001-0000-0010-0001 X25 reversed: 1-0000-1000-0001-0001

CRC16 standard: 1-1000-0000-0000-0101 CRC16 reversed: 1-0100-0000-0000-0011

Note that here it is the entire poly that is being reflected/reversed,not just the bottom W bits. This is an important distinction. In thereflected algorithm described in the previous section, the poly usedin the reflected algorithm was actually identical to that used in thenon-reflected algorithm; all that had happened is that the bytes hadeffectively been reflected. As such, all the 16-bit/32-bit numbers inthe algorithm had to be reflected. In contrast, the ENTIRE polyincludes the implicit one bit at the top, and so reversing a poly isnot the same as reflecting its bottom 16 or 32 bits.

The upshot of all this is that a reflected algorithm is not equivalentto the original algorithm with the poly reflected. Actually, this isprobably less confusing than if they were duals.

If all this seems a bit unclear, don't worry, because we're going tosort it all out "real soon now". Just one more section to go beforethat.

13. Initial and Final Values----------------------------In addition to the complexity already seen, CRC algorithms differ fromeach other in two other regards:

* The initial value of the register.

* The value to be XORed with the final register value.

For example, the "CRC32" algorithm initializes its register toFFFFFFFF and XORs the final register value with FFFFFFFF.

Most CRC algorithms initialize their register to zero. However, someinitialize it to a non-zero value. In theory (i.e. with no assumptionsabout the message), the initial value has no affect on the strength ofthe CRC algorithm, the initial value merely providing a fixed starting

Page 36: Adnet Information

point from which the register value can progress. However, inpractice, some messages are more likely than others, and it is wise toinitialize the CRC algorithm register to a value that does not have"blind spots" that are likely to occur in practice. By "blind spot" ismeant a sequence of message bytes that do not result in the registerchanging its value. In particular, any CRC algorithm that initializesits register to zero will have a blind spot of zero when it starts upand will be unable to "count" a leading run of zero bytes. As aleading run of zero bytes is quite common in real messages, it is wiseto initialize the algorithm register to a non-zero value.

14. Defining Algorithms Absolutely----------------------------------At this point we have covered all the different aspects oftable-driven CRC algorithms. As there are so many variations on thesealgorithms, it is worth trying to establish a nomenclature for them.This section attempts to do that.

We have seen that CRC algorithms vary in:

* Width of the poly (polynomial). * Value of the poly. * Initial value for the register. * Whether the bits of each byte are reflected before being processed. * Whether the algorithm feeds input bytes through the register or xors them with a byte from one end and then straight into the table. * Whether the final register value should be reversed (as in reflected versions). * Value to XOR with the final register value.

In order to be able to talk about particular CRC algorithms, we needto able to define them more precisely than this. For this reason, thenext section attempts to provide a well-defined parameterized modelfor CRC algorithms. To refer to a particular algorithm, we need thensimply specify the algorithm in terms of parameters to the model.

15. A Parameterized Model For CRC Algorithms--------------------------------------------In this section we define a precise parameterized model CRC algorithmwhich, for want of a better name, we will call the "Rocksoft^tm ModelCRC Algorithm" (and why not? Rocksoft^tm could do with some freeadvertising :-).

The most important aspect of the model algorithm is that it focussesexclusively on functionality, ignoring all implementation details. Theaim of the exercise is to construct a way of referring precisely toparticular CRC algorithms, regardless of how confusingly they areimplemented. To this end, the model must be as simple and precise aspossible, with as little confusion as possible.

The Rocksoft^tm Model CRC Algorithm is based essentially on the DIRECTTABLE ALGORITHM specified earlier. However, the algorithm has to befurther parameterized to enable it to behave in the same way as someof the messier algorithms out in the real world.

To enable the algorithm to behave like reflected algorithms, weprovide a boolean option to reflect the input bytes, and a booleanoption to specify whether to reflect the output checksum value. Byframing reflection as an input/output transformation, we avoid the

Page 37: Adnet Information

confusion of having to mentally map the parameters of reflected andnon-reflected algorithms.

An extra parameter allows the algorithm's register to be initializedto a particular value. A further parameter is XORed with the finalvalue before it is returned.

By putting all these pieces together we end up with the parameters ofthe algorithm:

NAME: This is a name given to the algorithm. A string value.

WIDTH: This is the width of the algorithm expressed in bits. This is one less than the width of the Poly.

POLY: This parameter is the poly. This is a binary value that should be specified as a hexadecimal number. The top bit of the poly should be omitted. For example, if the poly is 10110, you should specify 06. An important aspect of this parameter is that it represents the unreflected poly; the bottom bit of this parameter is always the LSB of the divisor during the division regardless of whether the algorithm being modelled is reflected.

INIT: This parameter specifies the initial value of the register when the algorithm starts. This is the value that is to be assigned to the register in the direct table algorithm. In the table algorithm, we may think of the register always commencing with the value zero, and this value being XORed into the register after the N'th bit iteration. This parameter should be specified as a hexadecimal number.

REFIN: This is a boolean parameter. If it is FALSE, input bytes are processed with bit 7 being treated as the most significant bit (MSB) and bit 0 being treated as the least significant bit. If this parameter is FALSE, each byte is reflected before being processed.

REFOUT: This is a boolean parameter. If it is set to FALSE, the final value in the register is fed into the XOROUT stage directly, otherwise, if this parameter is TRUE, the final register value is reflected first.

XOROUT: This is an W-bit value that should be specified as a hexadecimal number. It is XORed to the final register value (after the REFOUT) stage before the value is returned as the official checksum.

CHECK: This field is not strictly part of the definition, and, in the event of an inconsistency between this field and the other field, the other fields take precedence. This field is a check value that can be used as a weak validator of implementations of the algorithm. The field contains the checksum obtained when the ASCII string "123456789" is fed through the specified algorithm (i.e. 313233... (hexadecimal)).

With these parameters defined, the model can now be used to specify aparticular CRC algorithm exactly. Here is an example specification fora popular form of the CRC-16 algorithm.

Name : "CRC-16" Width : 16 Poly : 8005

Page 38: Adnet Information

Init : 0000 RefIn : True RefOut : True XorOut : 0000 Check : BB3D

16. A Catalog of Parameter Sets for Standards---------------------------------------------At this point, I would like to give a list of the specifications forcommonly used CRC algorithms. However, most of the algorithms that Ihave come into contact with so far are specified in such a vague waythat this has not been possible. What I can provide is a list of polysfor various CRC standards I have heard of:

X25 standard : 1021 [CRC-CCITT, ADCCP, SDLC/HDLC] X25 reversed : 0811

CRC16 standard : 8005 CRC16 reversed : 4003 [LHA]

CRC32 : 04C11DB7 [PKZIP, AUTODIN II, Ethernet, FDDI]

I would be interested in hearing from anyone out there who can tiedown the complete set of model parameters for any of these standards.

However, a program that was kicking around seemed to imply thefollowing specifications. Can anyone confirm or deny them (or providethe check values (which I couldn't be bothered coding up andcalculating)).

Name : "CRC-16/CITT" Width : 16 Poly : 1021 Init : FFFF RefIn : False RefOut : False XorOut : 0000 Check : ?

Name : "XMODEM" Width : 16 Poly : 8408 Init : 0000 RefIn : True RefOut : True XorOut : 0000 Check : ?

Name : "ARC" Width : 16 Poly : 8005 Init : 0000 RefIn : True RefOut : True XorOut : 0000 Check : ?

Here is the specification for the CRC-32 algorithm which is reportedly

Page 39: Adnet Information

used in PKZip, AUTODIN II, Ethernet, and FDDI.

Name : "CRC-32" Width : 32 Poly : 04C11DB7 Init : FFFFFFFF RefIn : True RefOut : True XorOut : FFFFFFFF Check : CBF43926

17. An Implementation of the Model Algorithm--------------------------------------------Here is an implementation of the model algorithm in the C programminglanguage. The implementation consists of a header file (.h) and animplementation file (.c). If you're reading this document in asequential scroller, you can skip this code by searching for thestring "Roll Your Own".

To ensure that the following code is working, configure it for theCRC-16 and CRC-32 algorithms given above and ensure that they producethe specified "check" checksum when fed the test string "123456789"(see earlier).

/******************************************************************************//* Start of crcmodel.h *//******************************************************************************//* *//* Author : Ross Williams ([email protected].). *//* Date : 3 June 1993. *//* Status : Public domain. *//* *//* Description : This is the header (.h) file for the reference *//* implementation of the Rocksoft^tm Model CRC Algorithm. For more *//* information on the Rocksoft^tm Model CRC Algorithm, see the document *//* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross *//* Williams ([email protected].). This document is likely to be in *//* "ftp.adelaide.edu.au/pub/rocksoft". *//* *//* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. *//* */

Page 40: Adnet Information

/******************************************************************************//* *//* How to Use This Package *//* ----------------------- *//* Step 1: Declare a variable of type cm_t. Declare another variable *//* (p_cm say) of type p_cm_t and initialize it to point to the first *//* variable (e.g. p_cm_t p_cm = &cm_t). *//* *//* Step 2: Assign values to the parameter fields of the structure. *//* If you don't know what to assign, see the document cited earlier. *//* For example: *//* p_cm->cm_width = 16; *//* p_cm->cm_poly = 0x8005L; *//* p_cm->cm_init = 0L; *//* p_cm->cm_refin = TRUE; *//* p_cm->cm_refot = TRUE; *//* p_cm->cm_xorot = 0L; *//* Note: Poly is specified without its top bit (18005 becomes 8005). *//* Note: Width is one bit less than the raw poly width. *//* *//* Step 3: Initialize the instance with a call cm_ini(p_cm); *//* *//* Step 4: Process zero or more message bytes by placing zero or more *//* successive calls to cm_nxt. Example: cm_nxt(p_cm,ch); *//* *//* Step 5: Extract the CRC value at any time by calling crc = cm_crc(p_cm); *//* If the CRC is a 16-bit value, it will be in the bottom 16 bits. *//* *//******************************************************************************/

Page 41: Adnet Information

/* *//* Design Notes *//* ------------ *//* PORTABILITY: This package has been coded very conservatively so that *//* it will run on as many machines as possible. For example, all external *//* identifiers have been restricted to 6 characters and all internal ones to *//* 8 characters. The prefix cm (for Crc Model) is used as an attempt to avoid *//* namespace collisions. This package is endian independent. *//* *//* EFFICIENCY: This package (and its interface) is not designed for *//* speed. The purpose of this package is to act as a well-defined reference *//* model for the specification of CRC algorithms. If you want speed, cook up *//* a specific table-driven implementation as described in the document cited *//* above. This package is designed for validation only; if you have found or *//* implemented a CRC algorithm and wish to describe it as a set of parameters *//* to the Rocksoft^tm Model CRC Algorithm, your CRC algorithm implementation *//* should behave identically to this package under those parameters. *//* *//******************************************************************************/

/* The following #ifndef encloses this entire *//* header file, rendering it indempotent. */#ifndef CM_DONE#define CM_DONE

/******************************************************************************/

/* The following definitions are extracted from my style header file which *//* would be cumbersome to distribute with this package. The DONE_STYLE is the *//* idempotence symbol used in my style header file. */

#ifndef DONE_STYLE

typedef unsigned long ulong;typedef unsigned bool;typedef unsigned char * p_ubyte_;

Page 42: Adnet Information

#ifndef TRUE#define FALSE 0#define TRUE 1#endif

/* Change to the second definition if you don't have prototypes. */#define P_(A) A/* #define P_(A) () */

/* Uncomment this definition if you don't have void. *//* typedef int void; */

#endif

/******************************************************************************/

/* CRC Model Abstract Type *//* ----------------------- *//* The following type stores the context of an executing instance of the *//* model algorithm. Most of the fields are model parameters which must be *//* set before the first initializing call to cm_ini. */typedef struct { int cm_width; /* Parameter: Width in bits [8,32]. */ ulong cm_poly; /* Parameter: The algorithm's polynomial. */ ulong cm_init; /* Parameter: Initial register value. */ bool cm_refin; /* Parameter: Reflect input bytes? */ bool cm_refot; /* Parameter: Reflect output CRC? */ ulong cm_xorot; /* Parameter: XOR this to output CRC. */

ulong cm_reg; /* Context: Context during execution. */ } cm_t;typedef cm_t *p_cm_t;

/******************************************************************************/

/* Functions That Implement The Model *//* ---------------------------------- *//* The following functions animate the cm_t abstraction. */

void cm_ini P_((p_cm_t p_cm));/* Initializes the argument CRC model instance. *//* All parameter fields must be set before calling this. */

void cm_nxt P_((p_cm_t p_cm,int ch));/* Processes a single message byte [0,255]. */

void cm_blk P_((p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len));/* Processes a block of message bytes. */

ulong cm_crc P_((p_cm_t p_cm));/* Returns the CRC value for the message bytes processed so far. */

Page 43: Adnet Information

/******************************************************************************/

/* Functions For Table Calculation *//* ------------------------------- *//* The following function can be used to calculate a CRC lookup table. *//* It can also be used at run-time to create or check static tables. */

ulong cm_tab P_((p_cm_t p_cm,int index));/* Returns the i'th entry for the lookup table for the specified algorithm. *//* The function examines the fields cm_width, cm_poly, cm_refin, and the *//* argument table index in the range [0,255] and returns the table entry in *//* the bottom cm_width bytes of the return value. */

/******************************************************************************/

/* End of the header file idempotence #ifndef */#endif

/******************************************************************************//* End of crcmodel.h *//******************************************************************************/

/******************************************************************************//* Start of crcmodel.c *//******************************************************************************//* *//* Author : Ross Williams ([email protected].). *//* Date : 3 June 1993. *//* Status : Public domain. *//* *//* Description : This is the implementation (.c) file for the reference *//* implementation of the Rocksoft^tm Model CRC Algorithm. For more */

Page 44: Adnet Information

/* information on the Rocksoft^tm Model CRC Algorithm, see the document *//* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross *//* Williams ([email protected].). This document is likely to be in *//* "ftp.adelaide.edu.au/pub/rocksoft". *//* *//* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. *//* *//******************************************************************************//* *//* Implementation Notes *//* -------------------- *//* To avoid inconsistencies, the specification of each function is not echoed *//* here. See the header file for a description of these functions. *//* This package is light on checking because I want to keep it short and *//* simple and portable (i.e. it would be too messy to distribute my entire *//* C culture (e.g. assertions package) with this package. *//* *//******************************************************************************/

#include "crcmodel.h"

/******************************************************************************/

/* The following definitions make the code more readable. */

#define BITMASK(X) (1L << (X))#define MASK32 0xFFFFFFFFL#define LOCAL static

/******************************************************************************/

LOCAL ulong reflect P_((ulong v,int b));LOCAL ulong reflect (v,b)/* Returns the value v with the bottom b [0,32] bits reflected. *//* Example: reflect(0x3e23L,3) == 0x3e26 */ulong v;int b;

Page 45: Adnet Information

{ int i; ulong t = v; for (i=0; i<b; i++) { if (t & 1L) v|= BITMASK((b-1)-i); else v&= ~BITMASK((b-1)-i); t>>=1; } return v;}

/******************************************************************************/

LOCAL ulong widmask P_((p_cm_t));LOCAL ulong widmask (p_cm)/* Returns a longword whose value is (2^p_cm->cm_width)-1. *//* The trick is to do this portably (e.g. without doing <<32). */p_cm_t p_cm;{ return (((1L<<(p_cm->cm_width-1))-1L)<<1)|1L;}

/******************************************************************************/

void cm_ini (p_cm)p_cm_t p_cm;{ p_cm->cm_reg = p_cm->cm_init;}

/******************************************************************************/

void cm_nxt (p_cm,ch)p_cm_t p_cm;int ch;{ int i; ulong uch = (ulong) ch; ulong topbit = BITMASK(p_cm->cm_width-1);

if (p_cm->cm_refin) uch = reflect(uch,8); p_cm->cm_reg ^= (uch << (p_cm->cm_width-8)); for (i=0; i<8; i++) { if (p_cm->cm_reg & topbit) p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly; else p_cm->cm_reg <<= 1; p_cm->cm_reg &= widmask(p_cm); }}

Page 46: Adnet Information

/******************************************************************************/

void cm_blk (p_cm,blk_adr,blk_len)p_cm_t p_cm;p_ubyte_ blk_adr;ulong blk_len;{ while (blk_len--) cm_nxt(p_cm,*blk_adr++);}

/******************************************************************************/

ulong cm_crc (p_cm)p_cm_t p_cm;{ if (p_cm->cm_refot) return p_cm->cm_xorot ^ reflect(p_cm->cm_reg,p_cm->cm_width); else return p_cm->cm_xorot ^ p_cm->cm_reg;}

/******************************************************************************/

ulong cm_tab (p_cm,index)p_cm_t p_cm;int index;{ int i; ulong r; ulong topbit = BITMASK(p_cm->cm_width-1); ulong inbyte = (ulong) index;

if (p_cm->cm_refin) inbyte = reflect(inbyte,8); r = inbyte << (p_cm->cm_width-8); for (i=0; i<8; i++) if (r & topbit) r = (r << 1) ^ p_cm->cm_poly; else r<<=1; if (p_cm->cm_refin) r = reflect(r,p_cm->cm_width); return r & widmask(p_cm);}

/******************************************************************************//* End of crcmodel.c *//******************************************************************************/

18. Roll Your Own Table-Driven Implementation---------------------------------------------

Page 47: Adnet Information

Despite all the fuss I've made about understanding and defining CRCalgorithms, the mechanics of their high-speed implementation remainstrivial. There are really only two forms: normal and reflected. Normalshifts to the left and covers the case of algorithms with Refin=FALSEand Refot=FALSE. Reflected shifts to the right and covers algorithmswith both those parameters true. (If you want one parameter true andthe other false, you'll have to figure it out for yourself!) Thepolynomial is embedded in the lookup table (to be discussed). Theother parameters, Init and XorOt can be coded as macros. Here is the32-bit normal form (the 16-bit form is similar).

unsigned long crc_normal (); unsigned long crc_normal (blk_adr,blk_len) unsigned char *blk_adr; unsigned long blk_len; { unsigned long crc = INIT; while (blk_len--) crc = crctable[((crc>>24) ^ *blk_adr++) & 0xFFL] ^ (crc << 8); return crc ^ XOROT; }

Here is the reflected form:

unsigned long crc_reflected (); unsigned long crc_reflected (blk_adr,blk_len) unsigned char *blk_adr; unsigned long blk_len; { unsigned long crc = INIT_REFLECTED; while (blk_len--) crc = crctable[(crc ^ *blk_adr++) & 0xFFL] ^ (crc >> 8)); return crc ^ XOROT; }

Note: I have carefully checked the above two code fragments, but Ihaven't actually compiled or tested them. This shouldn't matter toyou, as, no matter WHAT you code, you will always be able to tell ifyou have got it right by running whatever you have created against thereference model given earlier. The code fragments above are reallyjust a rough guide. The reference model is the definitive guide.

Note: If you don't care much about speed, just use the reference modelcode!

19. Generating A Lookup Table-----------------------------The only component missing from the normal and reversed code fragmentsin the previous section is the lookup table. The lookup table can becomputed at run time using the cm_tab function of the model packagegiven earlier, or can be pre-computed and inserted into the C program.In either case, it should be noted that the lookup table depends onlyon the POLY and RefIn (and RefOt) parameters. Basically, thepolynomial determines the table, but you can generate a reflectedtable too if you want to use the reflected form above.

The following program generates any desired 16-bit or 32-bit lookuptable. Skip to the word "Summary" if you want to skip over this code.

Page 48: Adnet Information

/******************************************************************************//* Start of crctable.c *//******************************************************************************//* *//* Author : Ross Williams ([email protected].). *//* Date : 3 June 1993. *//* Version : 1.0. *//* Status : Public domain. *//* *//* Description : This program writes a CRC lookup table (suitable for *//* inclusion in a C program) to a designated output file. The program can be *//* statically configured to produce any table covered by the Rocksoft^tm *//* Model CRC Algorithm. For more information on the Rocksoft^tm Model CRC *//* Algorithm, see the document titled "A Painless Guide to CRC Error *//* Detection Algorithms" by Ross Williams ([email protected].). This *//* document is likely to be in "ftp.adelaide.edu.au/pub/rocksoft". *//* *//* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. *//* *//******************************************************************************/

#include <stdio.h>#include <stdlib.h>#include "crcmodel.h"

/******************************************************************************/

/* TABLE PARAMETERS *//* ================ *//* The following parameters entirely determine the table to be generated. You *//* should need to modify only the definitions in this section before running */

Page 49: Adnet Information

/* this program. *//* *//* TB_FILE is the name of the output file. *//* TB_WIDTH is the table width in bytes (either 2 or 4). *//* TB_POLY is the "polynomial", which must be TB_WIDTH bytes wide. *//* TB_REVER indicates whether the table is to be reversed (reflected). *//* *//* Example: *//* *//* #define TB_FILE "crctable.out" *//* #define TB_WIDTH 2 *//* #define TB_POLY 0x8005L *//* #define TB_REVER TRUE */

#define TB_FILE "crctable.out"#define TB_WIDTH 4#define TB_POLY 0x04C11DB7L#define TB_REVER TRUE

/******************************************************************************/

/* Miscellaneous definitions. */

#define LOCAL staticFILE *outfile;#define WR(X) fprintf(outfile,(X))#define WP(X,Y) fprintf(outfile,(X),(Y))

/******************************************************************************/

LOCAL void chk_err P_((char *));LOCAL void chk_err (mess)/* If mess is non-empty, write it out and abort. Otherwise, check the error *//* status of outfile and abort if an error has occurred. */char *mess;{ if (mess[0] != 0 ) {printf("%s\n",mess); exit(EXIT_FAILURE);} if (ferror(outfile)) {perror("chk_err"); exit(EXIT_FAILURE);}}

Page 50: Adnet Information

/******************************************************************************/

LOCAL void chkparam P_((void));LOCAL void chkparam (){ if ((TB_WIDTH != 2) && (TB_WIDTH != 4)) chk_err("chkparam: Width parameter is illegal."); if ((TB_WIDTH == 2) && (TB_POLY & 0xFFFF0000L)) chk_err("chkparam: Poly parameter is too wide."); if ((TB_REVER != FALSE) && (TB_REVER != TRUE)) chk_err("chkparam: Reverse parameter is not boolean.");}

/******************************************************************************/

LOCAL void gentable P_((void));LOCAL void gentable (){ WR("/*****************************************************************/\n"); WR("/* */\n"); WR("/* CRC LOOKUP TABLE */\n"); WR("/* ================ */\n"); WR("/* The following CRC lookup table was generated automagically */\n"); WR("/* by the Rocksoft^tm Model CRC Algorithm Table Generation */\n"); WR("/* Program V1.0 using the following model parameters: */\n"); WR("/* */\n"); WP("/* Width : %1lu bytes. */\n", (ulong) TB_WIDTH); if (TB_WIDTH == 2) WP("/* Poly : 0x%04lX */\n", (ulong) TB_POLY); else WP("/* Poly : 0x%08lXL */\n", (ulong) TB_POLY); if (TB_REVER) WR("/* Reverse : TRUE. */\n"); else WR("/* Reverse : FALSE. */\n"); WR("/* */\n"); WR("/* For more information on the Rocksoft^tm Model CRC Algorithm, */\n"); WR("/* see the document titled \"A Painless Guide to CRC Error */\n");

Page 51: Adnet Information

WR("/* Detection Algorithms\" by Ross Williams */\n"); WR("/* ([email protected].). This document is likely to be */\n"); WR("/* in the FTP archive \"ftp.adelaide.edu.au/pub/rocksoft\". */\n"); WR("/* */\n"); WR("/*****************************************************************/\n"); WR("\n"); switch (TB_WIDTH) { case 2: WR("unsigned short crctable[256] =\n{\n"); break; case 4: WR("unsigned long crctable[256] =\n{\n"); break; default: chk_err("gentable: TB_WIDTH is invalid."); } chk_err("");

{ int i; cm_t cm; char *form = (TB_WIDTH==2) ? "0x%04lX" : "0x%08lXL"; int perline = (TB_WIDTH==2) ? 8 : 4;

cm.cm_width = TB_WIDTH*8; cm.cm_poly = TB_POLY; cm.cm_refin = TB_REVER;

for (i=0; i<256; i++) { WR(" "); WP(form,(ulong) cm_tab(&cm,i)); if (i != 255) WR(","); if (((i+1) % perline) == 0) WR("\n"); chk_err(""); }

WR("};\n"); WR("\n"); WR("/*****************************************************************/\n"); WR("/* End of CRC Lookup Table */\n"); WR("/*****************************************************************/\n"); WR(""); chk_err("");}}

/******************************************************************************/

main (){ printf("\n"); printf("Rocksoft^tm Model CRC Algorithm Table Generation Program V1.0\n"); printf("-------------------------------------------------------------\n"); printf("Output file is \"%s\".\n",TB_FILE);

Page 52: Adnet Information

chkparam(); outfile = fopen(TB_FILE,"w"); chk_err(""); gentable(); if (fclose(outfile) != 0) chk_err("main: Couldn't close output file."); printf("\nSUCCESS: The table has been successfully written.\n");}

/******************************************************************************//* End of crctable.c *//******************************************************************************/

20. Summary-----------This document has provided a detailed explanation of CRC algorithmsexplaining their theory and stepping through increasinglysophisticated implementations ranging from simple bit shifting throughto byte-at-a-time table-driven implementations. The variousimplementations of different CRC algorithms that make them confusingto deal with have been explained. A parameterized model algorithm hasbeen described that can be used to precisely define a particular CRCalgorithm, and a reference implementation provided. Finally, a programto generate CRC tables has been provided.

21. Corrections---------------If you think that any part of this document is unclear or incorrect,or have any other information, or suggestions on how this documentcould be improved, please context the author. In particular, I wouldlike to hear from anyone who can provide Rocksoft^tm Model CRCAlgorithm parameters for standard algorithms out there.

A. Glossary-----------CHECKSUM - A number that has been calculated as a function of somemessage. The literal interpretation of this word "Check-Sum" indicatesthat the function should involve simply adding up the bytes in themessage. Perhaps this was what early checksums were. Today, however,although more sophisticated formulae are used, the term "checksum" isstill used.

CRC - This stands for "Cyclic Redundancy Code". Whereas the term"checksum" seems to be used to refer to any non-cryptographic checkinginformation unit, the term "CRC" seems to be reserved only foralgorithms that are based on the "polynomial" division idea.

G - This symbol is used in this document to represent the Poly.

MESSAGE - The input data being checksummed. This is usually structuredas a sequence of bytes. Whether the top bit or the bottom bit of eachbyte is treated as the most significant or least significant is aparameter of CRC algorithms.

POLY - This is my friendly term for the polynomial of a CRC.

POLYNOMIAL - The "polynomial" of a CRC algorithm is simply the divisor

Page 53: Adnet Information

in the division implementing the CRC algorithm.

REFLECT - A binary number is reflected by swapping all of its bitsaround the central point. For example, 1101 is the reflection of 1011.

ROCKSOFT^TM MODEL CRC ALGORITHM - A parameterized algorithm whosepurpose is to act as a solid reference for describing CRC algorithms.Typically CRC algorithms are specified by quoting a polynomial.However, in order to construct a precise implementation, one alsoneeds to know initialization values and so on.

WIDTH - The width of a CRC algorithm is the width of its polynomicalminus one. For example, if the polynomial is 11010, the width would be4 bits. The width is usually set to be a multiple of 8 bits.

B. References-------------[Griffiths87] Griffiths, G., Carlyle Stones, G., "The Tea-Leaf ReaderAlgorithm: An Efficient Implementation of CRC-16 and CRC-32",Communications of the ACM, 30(7), pp.617-620. Comment: This paperdescribes a high-speed table-driven implementation of CRC algorithms.The technique seems to be a touch messy, and is superceded by theSarwete algorithm.

[Knuth81] Knuth, D.E., "The Art of Computer Programming", Volume 2:Seminumerical Algorithms, Section 4.6.

[Nelson 91] Nelson, M., "The Data Compression Book", M&T Books, (501Galveston Drive, Redwood City, CA 94063), 1991, ISBN: 1-55851-214-4.Comment: If you want to see a real implementation of a real 32-bitchecksum algorithm, look on pages 440, and 446-448.

[Sarwate88] Sarwate, D.V., "Computation of Cyclic Redundancy Checksvia Table Look-Up", Communications of the ACM, 31(8), pp.1008-1013.Comment: This paper describes a high-speed table-driven implementationfor CRC algorithms that is superior to the tea-leaf algorithm.Although this paper describes the technique used by most modern CRCimplementations, I found the appendix of this paper (where all thegood stuff is) difficult to understand.

[Tanenbaum81] Tanenbaum, A.S., "Computer Networks", Prentice Hall,1981, ISBN: 0-13-164699-0. Comment: Section 3.5.3 on pages 128 to 132provides a very clear description of CRC codes. However, it does notdescribe table-driven implementation techniques.

C. References I Have Detected But Haven't Yet Sighted-----------------------------------------------------Boudreau, Steen, "Cyclic Redundancy Checking by Program," AFIPSProceedings, Vol. 39, 1971.

Davies, Barber, "Computer Networks and Their Protocols," J. Wiley &Sons, 1979.

Higginson, Kirstein, "On the Computation of Cyclic Redundancy Checksby Program," The Computer Journal (British), Vol. 16, No. 1, Feb 1973.

McNamara, J. E., "Technical Aspects of Data Communication," 2ndEdition, Digital Press, Bedford, Massachusetts, 1982.

Marton and Frambs, "A Cyclic Redundancy Checking (CRC) Algorithm,"

Page 54: Adnet Information

Honeywell Computer Journal, Vol. 5, No. 3, 1971.

Nelson M., "File verification using CRC", Dr Dobbs Journal, May 1992,pp.64-67.

Ramabadran T.V., Gaitonde S.S., "A tutorial on CRC computations", IEEEMicro, Aug 1988.

Schwaderer W.D., "CRC Calculation", April 85 PC Tech Journal,pp.118-133.

Ward R.K, Tabandeh M., "Error Correction and Detection, A GeometricApproach" The Computer Journal, Vol. 27, No. 3, 1984, pp.246-253.

Wecker, S., "A Table-Lookup Algorithm for Software Computation ofCyclic Redundancy Check (CRC)," Digital Equipment Corporationmemorandum, 1974.

--<End of Document>--

Radio Frequency (RF) Carrier Signal

 

As mentioned above, a carrier sinusoid carries the information signal over the airwaves in the case of

radio transmission or though wires or optical fibres in the case of telephony or computer

communication.

The carrier for radio is a sinusoid with a high frequency. For example, the carrier frequency for FM

signals will be around 100 MHz which means that the transmitter will produce a sinewave which goes

through one cycle 100,000,000 times per second, or one cycle lasts for a period of 10 nanoseconds

(ns) which is 10 billionths of a second. A DAB carrier frequency will be around 200 MHz (for its

present use in band III) so would have a period of 5ns because the frequency is the reciprocal of the

period and vice versa, i.e.:

frequency = 1 / period

The carrier “carries” the information by being modulated by an information signal such as an audio

signal. Modulation just means “is modified in some way”. The easiest way to describe modulation is

using the example of amplitude modulation (AM). Here, the audio signal will alter the amplitude of the

carrier; when the amplitude of the audio signal goes up, the amplitude of the carrier goes up too by a

proportional amount, when the signal goes down, the carrier frequency goes down, and so on. For

frequency modulaton (FM), the amplitude of the audio signal changes the frequency of the carrier so

that when the amplitude of the audio signal goes up, the carrier frequency will be increased to a

higher frequency and when it does down the carrier frequency will go down. Another type of

modulation is phase modulation. Here the phase angle of the carrier is changed. This is more

important for digital modulation and will be dealt with later.

The audio signal is called a baseband signal or lowpass signal because its band of frequencies go

down to zero frequency, or DC (direct current) or to a low frequency relative to high frequencies such

as radio frequencies. For example, audio signals cover the range of frequencies from 20Hz up to

20kHz and so as this band of frequencies is very low in comparison with the radio frequency (RF)

carrier the audio signal is termed a baseband- or lowpass-signal.

Page 55: Adnet Information

The result of modulating the carrier with the baseband signal is that the band of frequencies

(spectrum) of the baseband signal is translated up to the carrier frequency, hence another name for

this is upconversion. One thing that confuses people not familiar with communication theory is that as

a result of using Fourier Theory, the signal contains negative as well as positive frequencies. Don’t

bother trying to visualize what negative frequency really means in the physical world and just accept

that a signal such as an audio signal is analyzed in the frequency domain using both positive and

negative frequencies components and an audio signal’s negative frequency components are the

mirror image of the positive frequency components, mirrored around zero Hz, so the spectrum looks

symmetrical and the symmetric axis is 0 Hz. The effect of translating this baseband spectrum up in

frequency though is that both the positive and negative frequency components are translated up in

frequency. For example, if you just multiplied the carrier frequency with a frequency of 100 MHz by a

baseband signal, this translates the baseband signal up in frequency so that the upconverted signal’s

spectrum now is symmetrical about the carrier frequency at 100 MHz. So, if you had a baseband

signal with a bandwidth of 20kHz and upconverted this signal by multiplying it by the carrier, the new

spectrum at the higher frequency will cover the frequency range 

f_high = 100 MHz + 20kHz = 100.02 MHz

down to

f_low = 100 MHz – 20 kHz = 99.98 MHz

so its bandwidth is:

B = f_high - f_low = 100.02 MHz - 99.98 MHz = 40 kHz

That is, because both the positive and negative frequency components have been translated up in

frequency the baseband bandwidth has doubled from the original 20 kHz to 40 kHz.

This higher frequency signal is called a passband signal as opposed to a baseband signal.

Radio signals are often converted first up to an intermediate frequency (IF), before being converted

higher to the radio frequency (RF). This is to do with filters being easier to build with a given frequency

response when the filter has a fixed centre frequency than are filters that have a variable centre

frequency. The centre frequency is halfway between the filter’s upper and lower cutoff frequencies

and a cutoff frequency is where the frequency outputs a frequency component with half the power that

it contained at the filter input.

As well as at the IF, there will be a filter at the higher RF, which is the final transmitter centre

frequency. This filter is used to limit the amount of power that strays into adjacent frequency bands

and thus interfere with signals in the adjacent bands.

Objectives

1. Know two reasons for using a carrier frequency 2. Be able to use a Power Density Spectrum to find:

1. efficiency 2. bandwidth

3. Know the relationship of carrier frequency, modulation frequency and modulation index to: 1. efficiency 2. bandwidth

Page 56: Adnet Information

4. Be able to explain why AM is limited to 33% efficiency and the consequence of trying to exceed that

Basic Communications System

The basic communications system has:

Transmitter: The sub-system that takes the information signal and processes it prior to transmission. The transmitter modulates the information onto a carrier signal, amplifies the signal and broadcasts it over the channel

Channel: The medium which transports the modulated signal to the receiver. Air acts as the channel for broadcasts like radio. May also be a wiring system like cable TV or the Internet.

Receiver: The sub-system that takes in the transmitted signal from the channel and processes it to retrieve the information signal. The receiver must be able to discriminate the signal from other signals which may using the same channel (called tuning), amplify the signal for processing and demodulate (remove the carrier) to retrieve the information. It also then processes the information for reception (for example, broadcast on a loudspeaker).

Modulation

The information signal can rarely be transmitted as is, it must be processed. In order to use electromagnetic transmission, it must first be converted from audio into an electric signal. The conversion is accomplished by a transducer. After conversion it is used to modulate a carrier signal.

A carrier signal is used for two reasons:

To reduce the wavelength for efficient transmission and reception (the optimum antenna size is ½ or ¼ of a wavelength). A typical audio frequency of 3000 Hz will have a wavelength of 100 km and would need an effective antenna length of 25 km! By comparison, a typical carrier for FM is 100 MHz, with a wavelength of 3 m, and could use an antenna only 80 cm long.

To allow simultaneous use of the same channel, called multiplexing. Each unique signal can be assigned a different carrier frequency (like radio stations) and still share the same channel. The phone company actually invented modulation to allow phone conversations to be transmitted over common lines.

The process of modulation means to systematically use the information signal (what you want to transmit) to vary some parameter of the carrier signal. The carrier signal is usually just a simple, single-frequency sinusoid (varies in time like a sine wave).

Page 57: Adnet Information

The basic sine wave goes like V(t) = Vo sin (2 f t + ) where the parameters are defined below:

V(t) the voltage of the signal as a function of time.

Vo the amplitude of the signal (represents the maximum value achieved each cycle)

f the frequency of oscillation, the number of cycles per second (also known as Hertz = 1 cycle per second)

the phase of the signal, representing the starting point of the cycle.

To modulate the signal just means to systematically vary one of the three parameters of the signal: amplitude, frequency or phase. Therefore, the type of modulation may be categorized as either

AM: amplitude modulation

FM: frequency modulation or

PM: phase modulation

Note: PM may be an unfamiliar term but is commonly used. The characteristics of PM are very similar to FM and so the terms are often used interchangeably.

AM

Amplitude modulation is the simplest of the three to understand. The transmitter just uses the information signal, Vm(t) to vary the amplitude of the carrier, Vco to produce a modulated signal, VAM(t). Here are the three signals in mathematical form:

Information: Vm(t) Carrier: Vc(t) = Vco sin (2 fc t + ) AM: VAM(t) = { Vco + Vm(t) }sin (2 fc t + )

Here, we see that the amplitude term has been replaced with the combination of the original amplitude plus the information signal. The amount of modulation depends on the amplitude of the information signal. This is usually expressed as a ratio of the maximum information signal to the amplitude of the carrier. We define:

Modulation Index

m = MAX(Vm(t) )/ Vco.

If the information signal is also a simple sine wave the modulation index has a simple form:

m = Vmo/Vco

Page 58: Adnet Information

The interpretation of the modulation index, m, may be expressed as: The fraction (percentage if multiplied by 100) of the carrier amplitude that it varies by. If m = 0.5, the carrier amplitude varies by 50 % above and below its original value. If m= 1.0 then it varies by 100%.

Here is a typical AM signal, showing the parts. Note that the information modulates the envelope of the carrier signal.

In this example, the modulation index is < 1.0 .

The AM Spectrum

A spectrum represents the relative amounts of different frequency components in any signal. Its like the display on the graphic-equalizer in your stereo which has leds showing the relative amounts of bass, midrange and treble. These correspond directly to increasing frequencies (treble being the high frequency components). It is a well-know fact of mathematics, that any function (signal) can be decomposed into purely sinusoidal components (with a few pathological exceptions) . In technical terms, the sines and cosines form a complete set of functions, also known as a basis in the infinite-dimensional vector space of real-valued functions (gag reflex). Given that any signal can be thought to be made up of sinusoidal signals, the spectrum then represents the "recipe card" of how to make the signal from sinusoids. Like: 1 part of 50 Hz and 2 parts of 200 Hz. Pure sinusoids have the simplest spectrum of all, just one component:

In this example, the carrier has 8 Hz and so the spectrum has a single component with value 1.0 at 8 Hz.

Page 59: Adnet Information

Now, the most basic amplitude modulated signal has a pretty simple spectrum. In this example, a pure sinusoid is used as the information signal (like the EBS test signal).

The carrier has a frequency of 65 Hz, and the information signal is at 5 Hz. The modulation index is 0.5. The spectrum reveals that there are so-called side-bands on either side of the carrier. This is known as the beat effect where two frequencies mix to produce the sum and difference frequencies. An example is when you tune a guitar string against another by playing the same note simultaneously. If they are not in tune, you can hear the "beat frequency" which is actually the difference between the two. AM works the opposite way: the "beat frequency" is the information which produces the side-bands. One can show the equivalence of these two approaches mathematically (but is slightly boring, so we won't do it).

It is useful to measure the range of frequencies that the entire signal occupies. This is known as the bandwidth (BW). In this example the bandwidth would be 10 Hz (70 Hz - 60 Hz). You can predict the bandwidth in this case using the simple formula: BW = 2fm where fm is the frequency of the simple sine wave used to modulate with.

A More Realistic Spectrum

The information signal is rarely a pure sinusoid (tone), but rather it is a complex mixture of pure sinusoids. As already mentioned, any signal can be decomposed into its pure sine and cosine functions. So it is fair to say that the information signal is just a combination (a spectrum itself) of many different tones. When a note is played on a trumpet, for example, there are actually several notes being played simultaneously. They are all related, and are called harmonics, meaning they are multiples of each other. When an entire orchestra plays, the spectrum rapidly becomes filled in with a wide variety of notes and their harmonics. This complexity is of course reflected in the spectrum of the AM signal used to transmit the music to your radio. A typical signal might look like this:

Page 60: Adnet Information

The carrier is at 65 Hz and the information signal used to modulate has its own spectrum ranging from about 1 to 11 Hz. The spectrum has the usual appearance: a strong carrier signal is the middle, and the two symmetrical side-bands. If you were to take only the upper side-band (USB), and downshift it starting at zero, you would recover the information signal. That is, in essence, what the receiver does when it demodulates.

Since the information signal is just "added on" to the carrier, we can easily predict the bandwidth: BW = 2 fm, where fm is now the maximum modulating frequency used (as opposed to the modulating frequency when a simple signal is used).

Example: AM Radio

AM radio is the most common example of this type of modulation. The frequency band used for AM radio is about 550 to 1720 kHz. This is the range of carrier frequencies available. The information transmitted is music and talk which falls in the audio spectrum. The full audio spectrum ranges up to 20 kHz, but AM radio limits the upper modulating frequency to 5 kHz. This results in a maximum bandwidth of 10 kHz. Therefore, the FCC can assign stations frequencies that are 10 kHz apart without fear of overlap (in reality, there still can be some overlap because the spectrum doesn't just end at the side-band, it actual kind of tapers off slowly. These "tails" can overlap if the signal is strong enough. You can make you receiver more selective by changing from the "distant" to the "local" setting to eliminate this at the expense of sensitivity). So if we fill up the AM band, assigning stations every 10 kHz, there are 107 available transmitter frequencies.

The practice of limiting the upper frequency to 5 kHz removes some of the original information (that which falls in the 5-20 kHz) range. Since the ability to exactly reproduce the signal is called fidelity, there is a loss of fidelity in AM broadcasts. This is one of the reasons that AM radio doesn't sound that good (compared to FM radio, as we will see later). Talk radio is relatively unaffected because conversation has very little of its signal above 5 kHz anyway. This might explain why talk radio is much more common on AM than FM.

AM Performance

Bandwidth

Now that the tools are in place, we can begin to make some evaluations of the performance of AM signals. The first example is bandwidth.

The bandwidth of a signal is always of significance for many reasons, but predominately, it determines how many channels (or stations) are available in a specific band. We saw that there could be a maximum of 107 AM radio stations. If you improved the fidelity of AM radio by making the upper modulating frequency 10 kHz, you would double the signal bandwidth, and as a result only be allowed 53 radio stations. If you tried to increase the AM band, you would lose some other band, like amateur radio.

The bandwidth of AM signals can be easily predicted using the now familiar formula: BW = 2 fm.

Page 61: Adnet Information

Efficiency

Since we are ultimately only concerned with the information and not the carrier, we don't want to waste a lot of energy in the carrier signal. You can define a measure of efficiency as follows:

= efficiency = PSB / PTOT

where: PSB = the power in all the side-bands

PTOT = the total transmitted power (includes carrier and side-bands)

The more strongly you modulate, the more power in put into the side-bands. We have already seen that the modulation index, m is the measure of how strongly you modulate. It may be interpreted at the fraction of the carrier amplitude that you modulate by. If m = 0.5, you vary the carrier by up to 50 % of its original value. It stands to reason, then, that if the modulation index is increased, that the efficiency will increase also. Then it would also stand to reason that you should use the largest value of modulation index, m , as possible. But we have not addressed the meaning modulating by more than 100% (m= 1.0).

It is possible to modulate by more than 100%. Here is a representative signal using m = 2.0:

The parameters are: carrier = 65 Hz, modulation = single tone at 5 Hz, m = 2.0

By all appearances, this is very successful. The efficiency looks to be about 0.67 (67 %). In fact, there is no problem at all when transmitting this signal. But there will be trouble in your receiver. The process of demodulation usually involves detecting the envelope of the AM signal. This may easily be accomplished by using a low-frequency filter (like a capacitor) which will remove the quickly oscillating carrier signal, leaving only the slowly-varying amplitude. But in this case, the envelope no longer matches what was put in: recall, we started with a simple single tone.

This is what we started with:

Page 62: Adnet Information

But after demodulation in the receiver, we have this:

What you see is the addition of a higher frequency component (a harmonic) to the original signal. Since we did not get back what was put in, this is known as distortion. The conclusion is that efficiency may be increased by increasing the value of the modulation index, m, but if you use a value > 1.0 there will be distortion introduced in the receiver. Unless you are listening to Metallica, this is generally undesirable. Therefore, the efficiency of AM transmission is limited by the restraint to keep m < 1.0. The numeric value of efficiency when m = 1.0 is about 33 %. We conclude that AM has a maximum practical efficiency of about 33 % due to the limitations placed on modulation index. If you try to improve the efficiency by raising m, you will introduce distortion when the signal is demodulated in the receiver.

Summary

A carrier is used to make the wavelength smaller for practical transmission and to permit multiplexing.

The spectrum is used to measure bandwidth (the range of frequencies) and the efficiency (the power in the side-bands compared to the total power)

Bandwidth can be predicted using BW = 2 fm where fm = the maximum modulating frequency Efficiency depends only on the modulating index, m (the fraction of the carrier you modulate

by) AM is limited to 33% efficiency because the modulation index cannot be increased to > 1.0

without introducing distortion in the receiver.