// --------------------------------------------------------------------------
// FUNCTION ComputeBufferCRC
// PURPOSE compute buffer CRC
// --------------------------------------------------------------------------
// INPUT dwCRC CRC initial value
// pvBuffer pointer to buffer to compute CRC for
// cbBuffer size of buffer in bytes
//
// OUTPUT DWORD CRC value
// --------------------------------------------------------------------------
// COMMENTS this function computes the CRC for a block of data.
// it accepts a CRC initial value and returns the updated value.
// uses dwCRCTable array.
// --------------------------------------------------------------------------
#pragma optimize("agt",on)
DWORD ComputeBufferCRC(DWORD dwCRC, void *pvBuffer, DWORD cbBuffer)
{
PBYTE pb;
DWORD dwTmp1, dwTmp2;
UINT i;
// --------------------------------------------------------------------------
// FUNCTION ComputeFileCRC
// PURPOSE compute file CRC
// --------------------------------------------------------------------------
// INPUT hf file handle
// lpOverlapped pointer to OVERLAPPED info for async. I/O
//
// OUTPUT DWORD CRC value
// --------------------------------------------------------------------------
// COMMENTS this function computes the CRC for a file. The CRC value is
// set with all 1's and then every it is inverted once the file
// hqs been done. This gives a CRC value that corresponds with
// the values calculated by PKZIP, ARJ...
// --------------------------------------------------------------------------
// Here is the adler32.c code, from the free compression library zLib,
// from Mark Adler and Jean-loup Gailly
// See on the web : http://quest.jpl.nasa.gov/zlib
#define BASE 65521L /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* $Id: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */
DWORD adler32 (DWORD adler, LPBYTE buf, UINT len)
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
int k;
if (buf == Z_NULL) return 1L;
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;
}
return (s2 << 16) | s1;
}
//}
This is a c project and it has been tested with Dev-C++ 4.9.7.1. I used these compiler options: -Os
-fno-rtti
-fno-exceptions
-falign-jumps=0
-fno-align-functions
-fomit-frame-pointer
-march=pentium
-mfpmath=387
-mrtd
-ffast-math
-s
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
//Start crc32.c
#include <windows.h>
#include "crc.c"
#include "crc32.h"
BOOL CALLBACK DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
char text[11] = "*Sorcerer*";
SendDlgItemMessage(hWnd,ListID1,LB_ADDSTRING,0,& text);
}
break;
case WM_COMMAND:
{
switch (LOWORD (wParam))
{
case ButtonID1:
{
OPENFILENAME ofn;
char szFile[MAX_PATH] = "";
HANDLE hf;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All files *.*\0*.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn)==TRUE)
{
DWORD crc = 0;
char crc32[10];
char crc32text[255] = "";
char file[MAX_PATH] = "";
hf = CreateFile(ofn.lpstrFile, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL);
InitializeCRCTable();
crc = ComputeFileCRC(hf, NULL);
CloseHandle(hf);
wsprintf(crc32, "%lX", crc);
GetFileTitle(ofn.lpstrFile, file, sizeof(file));
lstrcat(crc32text, file);
lstrcat(crc32text, " --> CRC32: ");
lstrcat(crc32text, crc32);
SendDlgItemMessage(hWnd,ListID1,LB_ADDSTRING,0,& crc32text);
}
}
break;
case ButtonID2:
SendMessage(hWnd,WM_CLOSE,0,0);
break;
}
}
break;
case WM_CLOSE:
EndDialog(hWnd,0);
break;
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
DialogBox(hInstance,MAKEINTRESOURCE(DialogID1),NULL,(DLGPROC)DlgProc);
return 0;
}
//End crc32.c
//Start crc32.rc
#include <windows.h>
#include "crc32.h"
DialogID1 DIALOG 51, 20, 273, 166
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Crc32"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "Open", ButtonID1, 68, 131, 40, 14
PUSHBUTTON "Exit", ButtonID2, 156, 131, 40, 14
GROUPBOX "", GroupID1, 6, 113, 261, 49
LISTBOX ListID1, 6, 6, 261, 111, WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
END
//End crc32.rc
//Start crc32.h
#define DialogID1 101
#define GroupID1 1001
#define ListID1 1002
#define ButtonID1 1003
#define ButtonID2 1004
//End crc32.h
//Start crc.c
// --------------------------------------------------------------------------
// MODULE CRC.C
// PURPOSE 32 bit CRC routines
// COPYRIGHT (c) Francois Liger, 1994
// --------------------------------------------------------------------------
// COMMENTS CRC 32 implementation complies with
// --------------------------------------------------------------------------
#include <windows.h>
#include "crc.h"
// --------------------------------------------------------------------------
// module wide definitions
// --------------------------------------------------------------------------
#define CRC_POLYNOMIAL 0xEDB88320L // standard polynomial constant
DWORD dwCRCTable[256]; // CRC table (1 KB)
// --------------------------------------------------------------------------
// FUNCTION InitializeCRCTable
// PURPOSE initializes CRC table with proper values
// --------------------------------------------------------------------------
// INPUT void
//
// OUTPUT void
// --------------------------------------------------------------------------
// COMMENTS
// --------------------------------------------------------------------------
void InitializeCRCTable(void)
{
int i, j;
DWORD dwCRC;
for(i = 0; i < 256; i++)
{
dwCRC = i;
for(j = 8; j > 0; j--)
{
if(dwCRC & 1)
dwCRC = (dwCRC >> 1) ^ CRC_POLYNOMIAL;
else
dwCRC >>= 1;
}
dwCRCTable[i] = dwCRC;
}
}
// --------------------------------------------------------------------------
// FUNCTION ComputeBufferCRC
// PURPOSE compute buffer CRC
// --------------------------------------------------------------------------
// INPUT dwCRC CRC initial value
// pvBuffer pointer to buffer to compute CRC for
// cbBuffer size of buffer in bytes
//
// OUTPUT DWORD CRC value
// --------------------------------------------------------------------------
// COMMENTS this function computes the CRC for a block of data.
// it accepts a CRC initial value and returns the updated value.
// uses dwCRCTable array.
// --------------------------------------------------------------------------
#pragma optimize("agt",on)
DWORD ComputeBufferCRC(DWORD dwCRC, void *pvBuffer, DWORD cbBuffer)
{
PBYTE pb;
DWORD dwTmp1, dwTmp2;
UINT i;
pb = (PBYTE)pvBuffer;
{
DWORD dwFour,dwRest;
dwFour = cbBuffer/8;
dwRest = cbBuffer - (dwFour*8);
for(i = 0; i < dwFour ; i++)
{
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *pb))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+1)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+2)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+3)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+4)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+5)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+6)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb+7)))]);
pb+=8;
/*
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb++)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb++)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb++)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb++)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb++)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb++)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb++)))]);
dwCRC = (dwCRC >> 8) ^ (dwCRCTable[(BYTE)(((BYTE)dwCRC ^ *(pb++)))]);
*/
}
for(i = 0; i < dwRest; i++)
{
dwTmp1 = (dwCRC >> 8) & 0x00FFFFFFL;
dwTmp2 = dwCRCTable[((int)dwCRC ^ *pb++) & 0xFF];
dwCRC = dwTmp1 ^ dwTmp2;
}
}
return dwCRC;
}
// --------------------------------------------------------------------------
// FUNCTION ComputeFileCRC
// PURPOSE compute file CRC
// --------------------------------------------------------------------------
// INPUT hf file handle
// lpOverlapped pointer to OVERLAPPED info for async. I/O
//
// OUTPUT DWORD CRC value
// --------------------------------------------------------------------------
// COMMENTS this function computes the CRC for a file. The CRC value is
// set with all 1's and then every it is inverted once the file
// hqs been done. This gives a CRC value that corresponds with
// the values calculated by PKZIP, ARJ...
// --------------------------------------------------------------------------
DWORD ComputeFileCRC(HANDLE hfile, LPOVERLAPPED lpOverlapped)
{
DWORD dwCRC;
BYTE bBuffer[CRC_BUFFER_SIZE];
DWORD cbBuffer;
// set CRC with 1's
dwCRC = 0xFFFFFFFFL;
// read file and compute CRC
for(;;)
{
ReadFile(hfile, &bBuffer, CRC_BUFFER_SIZE, &cbBuffer, lpOverlapped);
if(cbBuffer == 0)
break;
dwCRC = ComputeBufferCRC(dwCRC, &bBuffer, cbBuffer);
}
// invert CRC
return(dwCRC ^= 0xFFFFFFFFL);
}
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// Here is the adler32.c code, from the free compression library zLib,
// from Mark Adler and Jean-loup Gailly
// See on the web : http://quest.jpl.nasa.gov/zlib
#define BASE 65521L /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
/* ========================================================================= */
//extern "C" {
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* $Id: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */
DWORD adler32 (DWORD adler, LPBYTE buf, UINT len)
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
int k;
if (buf == Z_NULL) return 1L;
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;
}
return (s2 << 16) | s1;
}
//}
//End crc.c
//Start crc.h
// --------------------------------------------------------------------------
// MODULE CRC.H
// PURPOSE 32 bit CRC routines
// COPYRIGHT (c) Francois Liger, 1994
// --------------------------------------------------------------------------
// COMMENTS CRC 32 header file
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// module wide definitions
// --------------------------------------------------------------------------
#define CRC_BUFFER_SIZE 512 // CRC file read buffer size
// --------------------------------------------------------------------------
// function prototypes
// --------------------------------------------------------------------------
void InitializeCRCTable(void);
DWORD ComputeBufferCRC(DWORD dwCRC, void *pvBuffer, DWORD cbBuffer);
DWORD ComputeFileCRC(HANDLE hfile, LPOVERLAPPED lpOverlapped);
#define Z_NULL (0)
DWORD adler32 (DWORD adler, LPBYTE buf, UINT len);
//End crc.h
This is a c project and it has been tested with Dev-C++ 4.9.7.1. I used these compiler options: -Os
-fno-rtti
-fno-exceptions
-falign-jumps=0
-fno-align-functions
-fomit-frame-pointer
-march=pentium
-mfpmath=387
-mrtd
-ffast-math
-s
The source is free to use.
*Sorcerer*