Cyclic Redundancy Code Calculator | Lab Report |
Calculate CRC of Character String using CRC Calculator (Also see the FileCheck Lab Report for CRCs of Files, Directories, Volumes) Delphi 7 CLX Version (Windows) | ||
Calculate CRC of File using CRC Calculator |
Purpose
The purpose of the CRCCalculator is to displayinteractively the CRC-16 and CRC-32 values for a specified string or file. (The CRC-32values will match those computed by PKZIP.)
Crc 16 Calculation Example
Additional files, CRC16Dem and CRC32Dem,show how to create a command-line program to calculate CRC values. A 'C'command-line program is also available.
Materials and Equipment
Software Requirements
Windows 95/98/2000 and Delphi 3/4/5/6/7 (to recompile)
or
Linux and Kylix 3 (to recompile)
Hex File Crc 16 Calculator. CRC Calculator (Javascript) CRC width RadioButton: CRC-8 CRC-16 CRC-32 (Cyclic Redundancy Check) calculation for an detailed discussion of CRC calculation. Apr 24, 2004 Hello, does anyone know of a PC-based tool, that adds a CRC16 checksum at a given address in an intel HEX file? I would like to add an offline-CRC to my generated H86-file. Hex File Crc 16 Calculator Average ratng: 5,0/5 2509reviews. Users can select the desired algorithms and configure CRC parameters for Custom CRCs prior to pressing the 'Generate' button to calculate the checksums and digests.
Hardware Requirements
VGA display
Procedure
- Double click on the CRCCalculator.EXE icon to start the program (Windows), or run the program under Linux using ./CrcCalculator..
- Enter any text in the edit box.
- Observe the CRC-16 and CRC-32 values in decimal or hexadecimal.
- Select File tabsheet.
- Click on the Read button and select a file
- Observe the CRC-16 and CRC-32 values in decimal or hexadecimal.
Expected Values
Hex values do not change by version of Delphi, but the decimal values are intended to beunsigned. CRC-16 values have always been unsigned, but since there was no 4-byteunsigned integer in D1-D3, the decimal values are signed for the CRC-32 until the Delphi 4version.
Test String | CRC-16 Init Method 1 | CRC-16 Init Method 2 | CRC-32 Init Method 2 | Comments | |||
Decimal | Hex | Decimal | Hex | Decimal | Hex | ||
<null string> | 0 | 0000 | 0 | 0000 | 0 | 00000000 | Delphi 2 - 7, Kylix 3 |
abc | 38712 | 9738 | 43190 | A8B6 | 891568578 | 352441C2 | Delphi 2 - 7, Kylix 3 |
ABC | 38712 | 4521 | 31407 | 7AAF | -1551695032 | A3830348 | Delphi 2 - 3 |
2743272264 | Delphi 4 - 7, Kylix 3 | ||||||
This is a string | 19524 | 4C44 | 17157 | 4305 | 141976383 | 0876633F | Delphi 2 - 7, Kylix 3 |
See the Initialization/Finalizationdiscussion below for a description of Initialization Methods 1 and 2.
See Felipe Rocha Machado's comments aboutprinting 32-bit integers in D3.
The CRC-32s of the files abcLower.TXT, ABCupper.TXT, andThisIsAString.TXT in the CRCDelphi.ZIP file match the values above,which are also verified in the CRC32Dem.PAS command line program:
CRC-32 Bytes F i l e n a m e -------- -------- ------------------------ 352441C2 3 abcLower.TXT A3830348 3 ABCUpper.TXT 0876633F 16 ThisIsAString.TXT |
Discussion
CRC values, especially the CRC-32, are an extremely good way to verify theintegrity of a file. If the CRC-32 for a file stays the same, there is only anextremely small probability that the file has been changed -- about 1 in 4 billion. CRCs could be used as a preliminary verification tool to find identical files. Ifthe CRCs of two files do not match, the file are not the same. This could even beused to compare image files.
Lookup Tables. The 'hardware' method of computing CRCs involves bitmanipulations, which is very inefficient for a software computation. Instead ofcomputing the CRC bit-by-bit, a 256-element lookup table can be used to perform theequivalent of 8 bit operations at a time. (This is described in 'Byte-wise CRCCalculations' in IEEE Micro, June 1983, pp. 40-50.)
For a CRC-16, the lookup table consists of 256 2-byte WORDs (seebelow, or the CRC16.PASunit for the actual table, or the CRCTable programfor computation of the lookup table for the x16 + x15 + x2 + 1generator polynomial):
CONST table: ARRAY[0..255] OF WORD = ($0000,$C0C1,$C181,$0140,$C301,$03C0,$0280,$C241,$C601,$06C0,$0780, $C741,$0500,$C5C1,$C481,$0440,$CC01,$0CC0,$0D80,$CD41,$0F00,$CFC1, $CE81,$0E40,$0A00,$CAC1,$CB81,$0B40,$C901,$09C0,$0880,$C841,$D801, $18C0,$1980,$D941,$1B00,$DBC1,$DA81,$1A40,$1E00,$DEC1,$DF81,$1F40, $DD01,$1DC0,$1C80,$DC41,$1400,$D4C1,$D581,$1540,$D701,$17C0,$1680, $D641,$D201,$12C0,$1380,$D341,$1100,$D1C1,$D081,$1040,$F001,$30C0, $3180,$F141,$3300,$F3C1,$F281,$3240,$3600,$F6C1,$F781,$3740,$F501, $35C0,$3480,$F441,$3C00,$FCC1,$FD81,$3D40,$FF01,$3FC0,$3E80,$FE41, $FA01,$3AC0,$3B80,$FB41,$3900,$F9C1,$F881,$3840,$2800,$E8C1,$E981, $2940,$EB01,$2BC0,$2A80,$EA41,$EE01,$2EC0,$2F80,$EF41,$2D00,$EDC1, $EC81,$2C40,$E401,$24C0,$2580,$E541,$2700,$E7C1,$E681,$2640,$2200, $E2C1,$E381,$2340,$E101,$21C0,$2080,$E041,$A001,$60C0,$6180,$A141, $6300,$A3C1,$A281,$6240,$6600,$A6C1,$A781,$6740,$A501,$65C0,$6480, $A441,$6C00,$ACC1,$AD81,$6D40,$AF01,$6FC0,$6E80,$AE41,$AA01,$6AC0, $6B80,$AB41,$6900,$A9C1,$A881,$6840,$7800,$B8C1,$B981,$7940,$BB01, $7BC0,$7A80,$BA41,$BE01,$7EC0,$7F80,$BF41,$7D00,$BDC1,$BC81,$7C40, $B401,$74C0,$7580,$B541,$7700,$B7C1,$B681,$7640,$7200,$B2C1,$B381, $7340,$B101,$71C0,$7080,$B041,$5000,$90C1,$9181,$5140,$9301,$53C0, $5280,$9241,$9601,$56C0,$5780,$9741,$5500,$95C1,$9481,$5440,$9C01, $5CC0,$5D80,$9D41,$5F00,$9FC1,$9E81,$5E40,$5A00,$9AC1,$9B81,$5B40, $9901,$59C0,$5880,$9841,$8801,$48C0,$4980,$8941,$4B00,$8BC1,$8A81, $4A40,$4E00,$8EC1,$8F81,$4F40,$8D01,$4DC0,$4C80,$8C41,$4400,$84C1, $8581,$4540,$8701,$47C0,$4680,$8641,$8201,$42C0,$4380,$8341,$4100, $81C1,$8081,$4040); |
Given the above lookup table,the code for computing a CRC-16 is as follows (see initialization/finalizationbelow):
PROCEDURE CalcCRC16 (p: pByte; nbyte: WORD; VAR CRCvalue: WORD); VAR i: WORD; q: pByte; {The following is a little cryptic (but executes very quickly). The algorithm is as follows: 1. exclusive-or the input byte with the low-order byte of the CRC register to get an INDEX 2. shift the CRC register eight bits to the right 3. exclusive-or the CRC register with the contents of Table[INDEX] 4. repeat steps 1 through 3 for all bytes} BEGIN q := p; FOR i := 1 TO nBYTE DO BEGIN CRCvalue := Hi(CRCvalue) XOR Table[ q^ XOR Lo(CRCvalue) ]; INC(q) END END {CalcCRC16}; |
For a CRC-32, the lookup table consists of 256 4-byteDWORDs (also see the CRC32.PAS unit).
// The constants here are for the CRC-32 generator // polynomial, as defined in the Microsoft // Systems Journal, March 1995, pp. 107-108 CONST $76DC4190, $01DB7106, $98D220BC, $EFD5102A, $EDB88320, $9ABFB3B6, $03B6E20C, $74B1D29A, $9B64C2B0, $EC63F226, $756AA39C, $026D930A, |
Given the above lookup table,the code for computing a CRC-32 is as follows (see initialization/finalizationbelow):
// Use CalcCRC32 as a procedure so CRCValue can be passed in but // also returned. This allows multiple calls to CalcCRC32 for // the 'same' CRC-32 calculation. PROCEDURE CalcCRC32 (p: pointer; ByteCount: DWORD; VAR CRCValue: DWORD); // The following is a little cryptic (but executes very quickly). // The algorithm is as follows: // 1. exclusive-or the input byte with the low-order byte of // the CRC register to get an INDEX // 2. shift the CRC register eight bits to the right // 3. exclusive-or the CRC register with the contents of Table[INDEX] // 4. repeat steps 1 through 3 for all bytes VAR i: DWORD; q: ^BYTE; BEGIN q := p; FOR i := 0 TO ByteCount-1 DO BEGIN CRCvalue := (CRCvalue SHR 8) XOR Table[ q^ XOR (CRCvalue AND $000000FF) ]; INC(q) END END {CalcCRC32}; |
You can pass nearly any argument to this routine since the first parameteris a pointer. For a string, pass the address of the first character, for example:
CalcCRC32 (Addr(s[1]),LENGTH(s), CRC32);
To avoid an access violation in Delphi 4 (or later) make sure Length(s)> 0. (I'm not sure why Delphi 3 didn't complain.)
This routine can be used to verify the CRC32 table of constantshas not been accidentally modified. The following code in the CRC32 unitinitialization checks the 1024-byte array of DWORDs:
VAR CRC32Table: DWORD; BEGIN // Verify the table used to compute the CRCs has not been modified. // Thanks to Gary Williams for this suggestion, Jan. 2003. CRC32Table := $FFFFFFFF; CalcCRC32 (Addr(table[0]), SizeOf(table), CRC32Table); CRC32Table := NOT CRC32Table; IF CRC32Table <> $6FCF9E13 THEN ShowMessage('CRC32 Table CRC32 is ' + IntToHex(Crc32Table, 8) + ', expecting $6FCF9E13'); END {CRC32}. |
To compute the same CRC-32 as used in the PKZIP utility, start with a CRCvalueof $FFFFFFFF. After calling CalcCRC32 above (any number of times), thefinalization consists of a 1's complement of the CRCvalue. This can becomputed with the expression NOT CRCvalue in Delphi. Seeadditional details in the next section.
Initialization andFinalization. The initialization and finalization of the CRC computation are arbitrary. Many years ago when I first started computing CRCs, I set the initialvalue to 0 and did no finalization -- this is 'Method 1' describedabove under Expected Values.
CRC16 := 0; IF LENGTH(s) > 0 // Avoid access violation in D4 THEN CalcCRC16 (Addr(s[1]), LENGTH(s), CRC16); |
The 'standard' CRC-32 (the one used by PKZIP) startswith $FFFFFFFF as the initial value and then performs a 1's complement to yield the finalvalue -- this is 'Method 2' described above under ExpectedValues. Here's what is done in the CRC Calculator for CRC-32s:
CRC32 := $FFFFFFFF; // To match PKZIP IF LENGTH(s) > 0 // Avoid access violation in D4 THEN CalcCRC32 (Addr(s[1]), LENGTH(s), CRC32); CRC32 := NOT CRC32; // TO match PKZIP |
In the CRC16 computation the initial value is $FFFF with Method2.
[Thanks to Rolf Gebhardt and Glen Harman for pointing out an inconsistencyabout how finalization was handled in an earlier version of this article.]
CRC of a File. All the bytes of a file must bepassed to the CalcCRC routines, i.e., CalcCRC16 and CalcCRC32, to compute theCRC of a file. The older BlockRead I/O primitive is used in theCalcFileCRC16 routine in the CRC16 unit since BlockRead at one point was theonly way to read a binary stream of bytes. CalcFileCRC32 uses the morecontemporary memory stream to read the bytes of a file (when the StreamIOconditional compilation is defined).
// Use MemoryStream to read file in binary mode. PROCEDURE CalcFileCRC32 (FromName: STRING; VAR CRCvalue: DWORD; VAR TotalBytes: TInteger8; VAR error: WORD); VAR Stream: TMemoryStream; BEGIN error := 0; CRCValue := $FFFFFFFF; Stream := TMemoryStream.Create; TRY TRY Stream.LoadFromFile(FromName); IF Stream.Size > 0 THEN CalcCRC32 (Stream.Memory, Stream.Size, CRCvalue) EXCEPT ON E: EReadError DO error := 1 END; CRCvalue := NOT CRCvalue; TotalBytes := Stream.Size FINALLY Stream.Free END; END {CalcFileCRC32}; |
The above procedure assumes that the file will easily fit intomemory in a TMemoryStream. Unfortunately, this can be a bad assumptionespecially when some files are bigger than physical memory. For example,processing a 1 GB file in a memory stream with only 512 MB of physical memorymight at minimum will tax the virtual memory processing of the operatingsystem. For now, this isn't much of a problem.
See Ted Tøraasen'smodification for CRC-16s for buffers > 64 KB.
FileCheck Program. See the FileCheck Lab Report for informationabout creating CRCs of files, directories, or even whole volumes. ('Meta' CRCs -- that is, CRCs of CRCs of a well-ordered list of files-- used to detect changes in directories or whole disk volumes.)
Command Line Programs. The command line examples, CRC16Dem and CRC32Dem can becompiled from a DOS Window (assuming your path contains the Delphi bin directory)by entering:
DCC32 CRC16Dem.PAS or
DCC32 CRC32Dem.PAS
Study the CRC16Dem and CRC32Dem command line programsfor a way to calculate CRCs without a Windows interface.
The Delphi installation CD has a file CRC32.C, which shows howto compute CRC-32s, as well as the lookup table, in the directory InfoExtrasZlibSrc.
CRC Links
A Painless Guide to CRC Error Detection Algorithms
www.ross.net/crc/crcpaper.html
www.microconsultants.com/tips/crc/crc.txt
www.geocities.com/SiliconValley/Pines/8659/crc.htm
Peter Haas' Delphi unit for demonstration calculation of CRC,based on the document: 'A Painless Guide to CRC Error DetectionAlgorithms'
ftp://ftp.rocksoft.com/papers/crc_v3.txt
Peter Haas' unit contains functions to calculate a arbitrary CRC(up to 32 bit) by given parameters (Polynom, Init, XorOut, ReflectIn, ReflectOut).A
another part is the generation of a Lookup Table and the calculation with thistable. The unit can also used to find the parameters for a unknown CRCcalculation with trial and error. Last but not least, it contain the unit afunction, that creates Delphi source to calculate a CRC with the givenparameters in a separate application.
http://delphi.pjh2.de/units/download/CRCs.zip
Find code for CRC-16 CCITT here:
http://home.t-online.de/home/uwe.mnich/Wissen/Delphi/Utilities/Utilities.html
Cyclic Redundancy Check Computation (Texas InstrumentsApplication Report)
- Coding theory behind CRC
- Algorithms for CRC computation
www.ti.com/sc/docs/psheets/abstract/apps/spra530.htm
http://www-s.ti.com/sc/psheets/spra530/spra530.pdf
'For the Love of the Game' by Michael Barr, Embedded SystemsProgramming, Dec. 1999, pp. 47-54.
www.embedded.com/internet/9912/9912connect.htm
'Slow and Steady Never Lost the Race' by Michael Barr, EmbeddedSystems Programming, Jan. 2000, pp. 37-46. Shows how to compute CRC lookuptable. www.embedded.com/internet/0001/0001connect.htm
The CRC Pitstop is a repository for information on CRC and otherchecking algorithms
www.ross.net/crc
CRC and How to Reverse it
www.yates2k.net/anarchriz_crc.htm
www.woodmann.com/fravia/crctut1.htm
http://pilorama.com.ru/library/pdf/crcrevrs.pdf (in Russian)
CRC - Der Cyclic Redundancy Code (in German)
www.informatik.uni-frankfurt.de/~haase/crc.html
Understanding Cyclic Redundancy Check
www.4d.com/ACIDOC/CMU/CMU79909.HTM
Robert Lee's optimized code for CRC computation:
www.optimalcode.com/excrc.zip
Checksum-Algorithms: XOR16, XOR32, CRC32
http://delphi.icm.edu.pl/ftp/d20free/cipher.zip
Steve Schafer's UseNet Post showingcalculation of CRC-32 Lookup Table
Björn Kriedemann'sUseNet Post with CRC Unitfrom April 1997 DDJ: CRC16, XYZModemCRC16, CRC32
Lars Truijens's UseNet Post showingDelphi code for XModem CRC-16 (X16 + X12 + X5 + 1) with aLookup Table
CRC-16 (X16+X15+X2+1) without lookuptable, www.ibrtses.com/delphi/dcrc.html.
CRC-16 Calculator in VisualBasic by Stuart Rolfe
A CRC Calculator Unit provides three speed-optimized functions to compute(or continue computation of) a Cyclic Redundancy Check (CRC). Applicable to XModemprotocol (16-bit CRC), SEA's 'ARC' utility, PKZip (32-bit CRC) and many otherscompatible software, http://delphi.icm.edu.pl/ftp/d10free/crc.zip.
SWAG (Software Archive Group) CRC Snipets: Includes various CRC andChecksum routines
www.gdsoft.com/swag/downloads.html
www.gdsoft.com/swag/crc.zip (requires'Reader' program to view)
Algorithm of CRC-32 calculation for file
www.scalabium.com/faq/dct0048.htm
'Calculating CRC Checksums in C++' by Colin Mahoney inJune 1999 C/C++ Users Journal.
Algorithms Alfresco: Whirlpool (CRC Algorithms), Julian Bucknall unravels CRC, Delphi Magazine,Issue 48, August 1999.
Split and Join (use CRCs to verify copy is correct after a file issplit into separate floppy-size files and later rejoined)
www.undu.com/Articles/010511d.html
CRC-32 used in PNG graphics file format
http://www.libpng.org/pub/png/spec/PNG-Structure.html#CRC-algorithm
The D7 'Companion Tools' (Disk 1) has a directory nag_software_solutionscrc32_librarywith a CRC32.EXE file from NAG SoftwareSolutions.
Implementing CRCCs in Altera Devices
www.altera.com/literature/an/an049.pdf
See the CRC32 Library on CD #1 of the Delphi Studio Companion Tools.
Related:
Check Digits (credit cards and the 'Modulo 10' check digitalgorithm)
www.delphiforfun.org/Programs/Check_digits.htm
Related
MD5 Homepage(unofficial)
Useful literature:
'Procedure for Computing CRC-32 Values,' Microsoft Systems Journal,March 1995, pp. 107-108.
'Byte-wise CRC Calculations' by Aram Perez in IEEE Micro,June 1983, pp. 40-50. Shows how to create a lookup table which is the best way toimplement in software (versus the shifts that are done when implemented inhardware).
'A Tutorial on CRC Computations' by Tenkasi V. Ramabadran andSunil S. Gaitonde in IEEE Micro, August 1988, pp. 62-75.
'Cyclic Redundancy Checks for Data Integrity or Identity' byWilliam H. Press and Saul A. Teukolsky, Computers in Physics, Jul/Aug 1989, pp.88-91.
Standard Name | SDLC (CCITT) (X25) | CRC-16 | CRC-32 (Ethernet) |
Width | 16 bits | 16 bits | 32 bits |
Generator Polynomial | 10001000000100001 x16 + x12 + x5 + 1 | 11000000000000101 x16 + x15 + x2 + 1 | 100000100110000010001110110110111 x32 + x26 + x23 + x22 + x16 + x12 + x11 + |
Initial remainder | 0xFFFF | 0x0000 | 0xFFFFFFFF |
Final XOR value | 0x0000 | 0x0000 | 0xFFFFFFFF |
Other standard polynomials:
CRC-16 Reverse: x16 + x14 + x1 + 1
SDLC Reverse: x16 + x11 + x4 + 1
CRC-12: x12 + x11 + x3 + x2 +x1 + 1
Conclusions
CRC values, especially the CRC-32, are an extremely good way to verify theintegrity of a string or even a file.
Keywords
cyclic redundancy check, CRC-16, CRC-32, APPTYPE CONSOLE, lookup table, XOR, Comp,Int64, IntToHex, Addr, Delphi, Kylix
Files
CLX (Component Library for Cross-Platform --Windows or Linux)
Delphi 7 Source and CRCCalculator.EXE: CRCCLX.zip
Kylix 3 Source and CrcCalculator executable: CRCCLX.tar.gz
In Linux to extract files: gunzip < CRCCLX.tar.gz tar xvf -
VCL (Visual Component Library -- Windowsonly)
Delphi 2 - 6 Source and EXE (234 KB): CRCDelphi.ZIP (old version)
Borland C++ 5.02 'C' CRC-32 Source and EXE (45 KB): CRCc.ZIP
Use the 'make file' to compile: make -fcrc32.mak
Modify .mak file to point to correct location of wildargs.obj. The .mak file automatically performs a test that the results will match those ofPKZIP.) This command-line utility can be used with wildcards to find the CRC-32 offiles in a directory, for example: crc32 *.*
TuboPascal 5.5 program to compute valuesfor CRC-16 lookup table.