// Adler32.h #ifndef Adler32h #define Adler32h #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 /* Adler32 is another checksum algorithm that is used as a "quick and dirty" version of the CRC32 algorithm. It was developed by Mark Adler from Fletcher's checksum. You get a single 32-bit number that represents a block of data (of any size but >128 bytes preferably). If the data changes in any way (even a single bit) the Adler32 calculation would yield a completely different value. Usage: int Adler32=CAdler32().From(Buffer,Size); or use one instance for several Adler32s: CAdler32 Adler32; int Adler32a=Adler32.From(Buffer1,Size1); int Adler32b=Adler32.From(Buffer2,Size2); or if reading a file in blocks: CAdler32 Adler32; while(Read(Buffer, Size)) Adler32.From(Buffer, Size, true); int MyAdler32=Adler32.GetAdler32(); Test Vectors used in the tester are generated from the RFC1950 C implementation. There are no official test vectors. */ class CAdler32 { DWORD LastAdler32; public: CAdler32() {} virtual ~CAdler32() {} DWORD GetAdler32() const {return LastAdler32;} DWORD From(const char* Path) { DWORD OK; BYTE Buffer[1024]; HANDLE File=CreateFile(Path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(File) do { ReadFile(File, Buffer, sizeof(Buffer), &OK, NULL); From(Buffer, OK, true); }while(OK); CloseHandle(File); return GetAdler32(); } void Reset() {LastAdler32=1;} //Only use this to use one Adler32 class for a whole new checksum when only using From(...) with Partial=true. DWORD From(const BYTE* Buffer, DWORD Len, bool Partial=false) { if(!Len || !Buffer) return 0; register DWORD Adler32=(Partial ? LastAdler32 : LastAdler32=1); register DWORD s1=Adler32 & 0xFFFF; register DWORD s2=Adler32 >> 16; while(Len>0) { int k=(Len<5552 ? Len : 5552); //5552 is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 Len-=k; while(k--) {s1+=*Buffer++; s2+=s1;} //Modern processors will NOT benefit from coded loop optimisation techniques (unrolling)! s1%=65521; // 65521 is the largest prime smaller than 65536 s2%=65521; } return LastAdler32=(s2<<16)|s1; } }; #ifdef Assert // Run tests if Tester.h is included in stdafx.h namespace { // namespace prevents multiple definitions if instantiating in the header like this: struct Adler32Tester : Tester, CAdler32 { Adler32Tester() { Assert(From((BYTE*)"resume",6)==0x09150292); Assert(From((BYTE*)"resumé",6)==0x09990316); Assert(From((BYTE*)"Mark Adler",10)==0x13070394); Assert(From((BYTE*)"\x00\x01\x02\x03",4)==0x000e0007); Assert(From((BYTE*)"\x00\x01\x02\x03\x04\x05\x06\x07",8)==0x005c001d); Assert(From((BYTE*)"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",16)==0x02b80079); Assert(From((BYTE*)"\x41\x41\x41\x41",4)==0x028e0105); Assert(From((BYTE*)"\x42\x42\x42\x42\x42\x42\x42\x42",8)==0x09500211); Assert(From((BYTE*)"\x43\x43\x43\x43\x43\x43\x43\x43\x43\x43\x43\x43\x43\x43\x43\x43",16)==0x23a80431); } } _Adler32Tester; } #endif // def Assert #endif //ndef Adler32h