Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / C++
Article

CRC_32

Rate me:
Please Sign up or sign in to vote.
4.50/5 (9 votes)
9 Oct 2001CPOL3 min read 148.3K   5.5K   55   14
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 <a href="http: www.createwindow.com="" programming="" crc32="" crcfile.htm"="">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

Parameters :

None.

Returns :

Nothing.

DWORD CRC_32::CalcCRC(LPVOID buffer, UINT size, HWND ProgressWnd/*= NULL*/)

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

WM_CRC_THREAD_DONE Message

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
President
Canada Canada
Father of two, brother of two, child of two.
Spouse to one, uncle to many, friend to lots.
Farmer, carpenter, mechanic, electrician, but definitely not a plumber.
Likes walks with the wife, board games, card games, travel, and camping in the summer.
High school graduate, college drop-out.
Hobby programmer who knows C++ with MFC and the STL.
Has dabbled with BASIC, Pascal, Fortran, COBOL, C#, SQL, ASM, and HTML.
Realized long ago that programming is fun when there is nobody pressuring you with schedules and timelines.

Comments and Discussions

 
QuestionCRC32 Calc Pin
lindac20313-Apr-18 8:07
lindac20313-Apr-18 8:07 
QuestionHow I known which polynomial is used to calculate CRC Pin
Red1_KM3-Mar-07 8:10
professionalRed1_KM3-Mar-07 8:10 
GeneralNeed calcul polynomial Pin
Red1_KM2-Feb-07 9:36
professionalRed1_KM2-Feb-07 9:36 
GeneralRe: Need calcul polynomial Pin
PJ Arends3-Feb-07 11:53
professionalPJ Arends3-Feb-07 11:53 
QuestionRe: Need calcul polynomial Pin
Red1_KM3-Mar-07 8:12
professionalRed1_KM3-Mar-07 8:12 
Generalwarnings Pin
Warren Stevens18-Jan-06 6:12
Warren Stevens18-Jan-06 6:12 
GeneralRe: warnings Pin
PJ Arends18-Jan-06 9:22
professionalPJ Arends18-Jan-06 9:22 
GeneralThread Termination Pin
Blake Miller10-Apr-03 6:12
Blake Miller10-Apr-03 6:12 
GeneralHashing URLs Pin
Anonymous8-Sep-02 23:33
Anonymous8-Sep-02 23:33 
GeneralRe: Hashing URLs Pin
PJ Arends8-Sep-02 23:51
professionalPJ Arends8-Sep-02 23:51 
GeneralBad checksum algorithm Pin
10-Oct-01 7:27
suss10-Oct-01 7:27 
GeneralRe: Bad checksum algorithm Pin
PJ Arends10-Oct-01 11:13
professionalPJ Arends10-Oct-01 11:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.