This is C++ source code tested in Visual Studio 2008 that creates 32 bit hash value of a file using the CRC32 algorithm. This hash value can be used as a fingerprint of a file. However these days of so many files lot of software programs and tools are using MD5 or better hash algorithms to get the fingerprint of a file. The CRC32 is mostly used to hash blocks of buffer for integrity checks. Either way CRC32 is still popular algorithm and can be used for many other reasons.

Code:
#include <stdio.h>

typedef unsigned long ULONG;

void InitCrcTable(void);
ULONG Reflect(ULONG , char);
int Get_CRC(unsigned char*, ULONG);
long FileSize(FILE*);


ULONG crc32_table[256];
ULONG ulPolynomial = 0x04c11db7;

///////////////////////////////////////////////////////////

void main(int arg, char **sarg)
{ 

 if(arg < 2)
 {
  printf("\nUsage: crcf.exe <file>\n");
  return;
 }

 FILE *fs = fopen(sarg[1], "rb");   //open file for reading 


 if(fs == NULL)
 {
  printf("\nError opening file %s\n", sarg[1]);
  return;
 }

  int crc;
  long bufsize = FileSize(fs), result;
  unsigned char *buffer = new unsigned char[bufsize];

  if(buffer == NULL)
  {
    printf("\nError out of memory\n");
    return;

  }
  
   // copy the file into the buffer:
  result = fread (buffer,1,bufsize,fs);
  fclose(fs);

  if(result != bufsize) 
  {
    printf("\nError reading file %s\n", sarg[1]);
    return;
  }

 
  InitCrcTable(); 
  crc = Get_CRC(buffer, bufsize);
  printf("\nCRC: 0x%X\n",crc);
  delete [] buffer;

}


///////////////////////////////////////////////////////////////////

void InitCrcTable()
{

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

}

//////////////////////////////////////////////////////////////
// Reflection is a requirement for the official CRC-32 standard.
// You can create CRCs without it, but they won't conform to the standard.
//////////////////////////////////////////////////////////////////////////

ULONG Reflect(ULONG ref, char ch)
{                                 // Used only by Init_CRC32_Table()

    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;
}

///////////////////////////////////////////////////////////////

int Get_CRC(unsigned char* buffer, ULONG bufsize)
{

    ULONG  crc(0xffffffff);
    int len;
    len = bufsize;
    // Save the text in the buffer.

    // Perform the algorithm on each character
    // in the string, using the lookup table values.

    for(int i = 0; i < len; i++)
          crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ buffer[i]];
    

    // Exclusive OR the result with the beginning value.
    return crc^0xffffffff;

}

////////////////////////////////////////////////////////////

long FileSize(FILE *input)
{

  long fileSizeBytes;
  fseek(input, 0, SEEK_END);
  fileSizeBytes = ftell(input);
  fseek(input, 0, SEEK_SET);

  return fileSizeBytes;
 

}