ECRC32, fast, easy to use CRC-32 checksum routines

A very small and simple unit which provides fast CRC-32 routines, probably faster than most 16-bit routines, because using 32-bits assembler/variables eases programming a unit like this considerably.

At the moment of writing, the Pascal version of CalcCrc wasn't operational, because of a problem in the open-array handling. Please check the header of the unit for more information.



Poly32

Declaration

CONST Poly32 : CARDINAL = $0EDB88320;

Description

Poly32 is a 32-bits seedvalue for the CreateCRC32Table procedure.

This is the standard polynome, used by 99.9% of the programmers. The CRC's you see when you list archives (pkunzip -v or arj l), or in WinZip, are all created with this polynomal. If you stick to the procedure used in the example for this unit, you will get the same crc-value as e.g. ARJ for a certain file.

The only reason not to use this standard polynomal is for anti-hacking purposes.

Example : see ECRC32 unit example



CreateCRC32Table

Declaration

PROCEDURE CreateCRC32Table( Poly32 : CARDINAL);

Description

This procedure must be called prior to any use of the CRC-calculating routines.

The procedure generates an internal, 256 elements big table of 32-bits CRC-codes on the heap which is needed for fast byte/character-based CRC calculations. The parameter is a certain seed (corresponding with a polynomal I believe) which is used to create the table.

If you want your CRC's to be compatible with other programs (like ARJ,ZIP and dozens of others), you should use Poly32 as parameter

The generation of the table is very fast, and only has to be done once. (but more calls to CreateCRC32Table are allowed).

Example : see ECRC32 unit example



CalcCRC

Declaration

FUNCTION CalcCRC (crc: CARDINAL;Buffer;BufSize:CARDINAL) : CARDINAL;

Description

Calculates a CRC-32 checksum value over the first BufSize bytes in Buffer.

The function returns the calculated CRC value. The crc parameter, is equal to $FFFFFFF if you use the procedure for the first time, or equal to the value returned by a previous call to CalcCRC. See the example for more details.

For performance reasons CalcCRC doesn't call AddCRC, the AddCRC code is included in CalcCRC

Example : see ECRC32 unit example



AddCRC

Declaration

PROCEDURE AddCRC( VAR crc : CARDINAL;ch : BYTE );

Description

Calculates a CRC-32 over one byte, updates value CRC (from previous AddCRC or CalcCRC calls, or $0FFFFFFFF if this is the first byte) to new CRC value

Not really meant to be called in a loop, use CalcCRC to calculate a CRC over a big memory chunk.

Some structures add 4 zero-bytes to the end of the to be crc'ed data. AddCrc is meant to calculate a CRC over those 4 zero bytes if you can't simply store 4 extra zero's after the data

Example : see ECRC32 unit example



InvertCRC

Declaration

FUNCTION InvertCRC(crc : CARDINAL ):CARDINAL;

Description

XOR's a crc-value with -1. If you calculate a crc using CalcCRC, you should use this procedure on the value to obtain a standard CRC.

Example : see ECRC32 unit example



ECRC32 unit example

This is an example how to calculate a CRC over a file on disk. You can pack the same file with ARJ or ZIP, and use Winzip, pkunzip -v or ARJ l to view the CRC-value calculated by the compressor, and compare it to the one generated by this example.

PROGRAM CRCTEST;        {Tested}

USES ECrc32,EFIO;      { EFIO is only used to display a value in HEX form}

CONST FileName='test.dat';      {Make sure the file exists, and size>0}

VAR F           : File;
    Buffer      : ARRAY[0..2047] OF BYTE; { 2kb buffer, but CalcCRC
                                            can process a Gigabyte buffer}
    BytesRead   : WORD;
    Crc         : CARDINAL;

BEGIN
 CreateCRC32Table(Poly32);              { Generate the CRC table}
 Assign(F,Filename);
 Reset(F,1);
 CRC:=$0FFFFFFFF;                       { Standard start-value}
 REPEAT
  BlockRead(F,Buffer,2048,BytesRead);   { Read a chunk}
  Crc:=CalcCrc(CRC,Buffer,BytesRead);   { calculate a CRC over the chunk}
 UNTIL BytesRead<>2048;                 { Until end-of-file}
 Close(F);
 WrLngHex(InvertCRC(CRC));              { Invert CRC and display}
 Writeln;
END. {CRCTEST}