12,297,982 members (56,472 online)
alternative version

120K views
54 bookmarked
Posted

# CRC_32

, 9 Oct 2001 CPOL
 Rate this:
A class that implements the CRC-32 Cyclic Redundancy Check Algorithm (MultiThreaded with Progress Bar support)

## Introduction

I recently needed the ability to calculate a CRC-32 value for some very large files, and I wanted to have a progress bar showing the progress of the calculation. I was able to find the algorithm at CreateWindow.com that I modified to suit my needs. The class I came up with is the `CRC_32` class which is defined in the CRC_32.h and CRC_32.cpp files included in the demo project.

## Testing

This class was not tested with UNICODE builds, nor was it tested on a network with UNC paths. If you find and fix any bugs, dropping me a note at pja@telus.net would be nice.

## Known Problem

If the CRC-32 calculations are run in a separate thread, and the thread is terminated prematurely, a memory leak occurs.

## The CRC-32 Algorithm

The first step in calculating the CRC-32 value for a data object (a file or any in memory data buffer) is to set up the lookup table. The table consists of 256 unique 32 bit values, one for each character in the ASCII table (0x00 -> 0xFF). The table can be declared as a static table in the source code, or it can be built dynamically at run time. I chose to build the table in the CRC_32 class constructor

```CRC_32::CRC_32()
{
// This is the official polynomial used by CRC-32
// in PKZip, WinZip and Ethernet.
ULONG ulPolynomial = 0x04C11DB7;

// 256 values representing ASCII character codes.
for(int i = 0; i <= 0xFF; i++)
{
Table[i] = Reflect(i, 8) << 24;
for (int j = 0; j < 8; j++)
Table[i] = (Table[i] << 1) ^ (Table[i] & (1 << 31) ? ulPolynomial : 0);
Table[i] = Reflect(Table[i],  32);
}
}

ULONG CRC_32::Reflect(ULONG ref, char ch)
{
ULONG value = 0;
// Swap bit 0 for bit 7
// bit 1 for bit 6, etc.
for (int i = 1; i < (ch + 1); i++)
{
if (ref & 1)
value |= 1 << (ch - i);
ref >>= 1;
} return value;
}```

Now that the lookup table has been initialized, it can be used to calculate the CRC-32 value of some data by passing the data through the `Calculate()` function.

```void CRC_32::Calculate(const LPBYTE buffer, UINT size, ULONG &CRC)
{   // calculate the CRC
LPBYTE pbyte = buffer;

while(size--)
CRC = (CRC >> 8) ^ Table[(CRC & 0xFF) ^ *pbyte++];
}```

The initial value of the CRC is set to 0xFFFFFFFF, then it is passed through the `Calculate()` function, and then the final value is XORed with the initial value to generate the CRC-32 value for the data

```DWORD CRC = 0xFFFFFFFF;
Calculate ((LPBYTE)buffer, size, CRC);
return CRC ^ 0xFFFFFFFF;```

## User Functions

### CRC_32::CRC32()

Constructs the CRC_32 class object

None.

Nothing.

### DWORD CRC_32::CalcCRC(LPCTSTR FileName, HWND ProgressWnd/*= NULL*/)

Calculates the CRC-32 value for the given buffer or file.

#### Parameters :

`buffer [in]` : a pointer to the data bytes.

`size [in]` : the size of the buffer.

`FileName [in]` : the complete path to the file.

`ProgressWnd [in]` : the `HWND` of the progress bar.

#### Returns :

• The CRC-32 value of the buffer or file if the `ProgressWnd` is not a window.
• The `HANDLE` of the created thread if the `ProgressWnd` is a window.
• `NULL` if an error occurs.

#### Note :

`ProgressWnd` is passed through the `IsWindow()` API function. If `IsWindow()` returns zero, `CalcCRC()` will calculate the CRC-32 value directly. If `IsWindow()` returns nonzero, `CalcCRC()` will start a separate thread. The thread will send PBM_* progress bar messages to the `ProgressWnd`. When the thread is finished, the thread will send a `WM_CRC_THREAD_DONE` message to the parent window of the `ProgressWnd` (usually a dialog window).

The `WM_CRC_THREAD_DONE` message is sent to the parent window of the Progress bar window passed to the `CalcCRC()` function when the thread has finished executing.

• Thread = `(HANDLE)wParam`
• CRC32 = `(ULONG)lParam`

Thread is the HANDLE of the thread that sent the `WM_CRC_THREAD_DONE` message. CRC32 is the CRC-32 value of the data passed into the thread. If CRC32 is zero, an error occurred.

## Share

No Biography provided

## You may also be interested in...

 First Prev Next
 How I known which polynomial is used to calculate CRC Redhouane_KM3-Mar-07 8:10 Redhouane_KM 3-Mar-07 8:10
 Need calcul polynomial Redhouane_KM2-Feb-07 9:36 Redhouane_KM 2-Feb-07 9:36
 Re: Need calcul polynomial PJ Arends3-Feb-07 11:53 PJ Arends 3-Feb-07 11:53
 Re: Need calcul polynomial Redhouane_KM3-Mar-07 8:12 Redhouane_KM 3-Mar-07 8:12
 warnings Warren D Stevens18-Jan-06 6:12 Warren D Stevens 18-Jan-06 6:12
 Re: warnings PJ Arends18-Jan-06 9:22 PJ Arends 18-Jan-06 9:22
 Thread Termination Blake Miller10-Apr-03 6:12 Blake Miller 10-Apr-03 6:12
 It is possible that the thread leaks memory if terminated prematurely for at least two reasons. 1. you allocate memory that is not freed unless thread exits gracefully (the obvious answer). 2. you use ::CreateThread instead of _beginthreadex. If you read about ::CreateThread versus _beginthreadex, you will see that there are warnings against using C run time library functions unless your thread is started with _beginthreadex. This might contribute to your problem. I did not further investigate (the not so obvious answer). C++/MFC/InstallShield since 1993
 Hashing URLs Anonymous8-Sep-02 23:33 Anonymous 8-Sep-02 23:33
 Re: Hashing URLs PJ Arends8-Sep-02 23:51 PJ Arends 8-Sep-02 23:51
 Bad checksum algorithm C-J Berg10-Oct-01 7:27 C-J Berg 10-Oct-01 7:27
 Re: Bad checksum algorithm PJ Arends10-Oct-01 11:13 PJ Arends 10-Oct-01 11:13
 Last Visit: 31-Dec-99 18:00     Last Update: 27-May-16 15:06 Refresh 1