{----------------------------------------------------------------------------- Checksum (History++ project) Version: 1.0 Created: 29.03.2003 [ Description ] [ History ] -----------------------------------------------------------------------------} {Copyright: Hagen Reddmann mailto:HaReddmann@AOL.COM Author: Hagen Reddmann Remarks: freeware, but this Copyright must be included known Problems: none Version: 3.0, Delphi Encryption Compendium Delphi 2-4, BCB 3-4, designed and testet under D3 and D4 Description: Utilitys for the DEC Packages * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } unit Checksum; interface uses SysUtils, Windows, Base64; type TDig64 = array[0..1] of DWord; function DigToBase(Digest: TDig64): AnsiString; function BaseToDig(Str: AnsiString): TDig64; //function StrToDig(Str: AnsiString): TDig64; function DigToStr(Digest: TDig64): AnsiString; function SameDigest(Dig1,Dig2: TDig64): Boolean; procedure CalcCRC32(Data: Pointer; DataSize: DWord; var CRCValue: DWord); //function CRC32(CRC: DWord; Data: Pointer; DataSize: DWord): LongWord; assembler; //function CRC32a(CRC: DWord; Data: Pointer; DataSize: DWord): DWord; function HashString(Str: AnsiString): TDig64; procedure CalcSampleHash(const Data: Pointer; DataSize: Integer; var Digest: TDig64); var ZeroDig: TDig64 = (0,0); implementation const DIGEST_DIV = '-'; const InitDigest: TDig64 = ($F3C55C5C,$05000000); InitCRC: DWord = $F3C55C5C; function DigToBase(Digest: TDig64): AnsiString; var DigStr: AnsiString; begin SetLength(DigStr, SizeOf(Digest)); Move(Digest, DigStr[1], SizeOf(Digest)); Result := Base64EncodeStr(DigStr); end; function BaseToDig(Str: AnsiString): TDig64; var DigStr: AnsiString; begin DigStr := Base64DecodeStr(Str); Move(DigStr[1], Result, SizeOf(Result)); end; function HashString(Str: AnsiString): TDig64; begin Result := ZeroDig; Result[0] := InitCRC; CalcCRC32(@Str[1], Length(Str), Result[0]); // CalcSampleHash(@Str[1],Length(Str),Result); end; (* function StrToDig(Str: AnsiString): TDig64; var Dig1, Dig2: AnsiString; n: Integer; begin Result[0] := 0; Result[1] := 0; n := Pos(DIGEST_DIV, Str); if n = 0 then exit; Dig1 := Copy(Str, 1, n - 1); Dig2 := Copy(Str, n + 1, Length(Str)); Result[0] := StrToInt('$' + Dig1); Result[1] := StrToInt('$' + Dig2); end; *) function DigToStr(Digest: TDig64): AnsiString; begin Result := AnsiString(IntToHex(Digest[0], 8)) + DIGEST_DIV + AnsiString(IntToHex(Digest[1], 8)); end; function SameDigest(Dig1, Dig2: TDig64): Boolean; begin Result := (Dig1[0] = Dig2[0]) and (Dig1[1] = Dig2[1]); end; { function CRC32a(CRC: DWord; Data: Pointer; DataSize: DWord): DWord; begin Result := CRC32(CRC,Data,DataSize); end; } type PInteger = ^Integer; procedure CalcSampleHash(const Data: Pointer; DataSize: Integer; var Digest: TDig64); var B: ^DWord; T: DWord; begin Digest := InitDigest; B := Data; while DataSize >= SizeOf(DWord) do begin T := Digest[0]; Inc(Digest[0], B^); if Digest[0] < T then Inc(Digest[1]); Inc(B); Dec(DataSize, SizeOf(DWord)); end; if DataSize > 0 then begin T := 0; Move(B^, T, DataSize); Inc(Digest[0], T); end; end; const CRC32Table: array[0..255] of DWord = ($00000000, $77073096, $EE0E612C, $990951BA, $076DC419, $706AF48F, $E963A535, $9E6495A3, $0EDB8832, $79DCB8A4, $E0D5E91E, $97D2D988, $09B64C2B, $7EB17CBD, $E7B82D07, $90BF1D91, $1DB71064, $6AB020F2, $F3B97148, $84BE41DE, $1ADAD47D, $6DDDE4EB, $F4D4B551, $83D385C7, $136C9856, $646BA8C0, $FD62F97A, $8A65C9EC, $14015C4F, $63066CD9, $FA0F3D63, $8D080DF5, $3B6E20C8, $4C69105E, $D56041E4, $A2677172, $3C03E4D1, $4B04D447, $D20D85FD, $A50AB56B, $35B5A8FA, $42B2986C, $DBBBC9D6, $ACBCF940, $32D86CE3, $45DF5C75, $DCD60DCF, $ABD13D59, $26D930AC, $51DE003A, $C8D75180, $BFD06116, $21B4F4B5, $56B3C423, $CFBA9599, $B8BDA50F, $2802B89E, $5F058808, $C60CD9B2, $B10BE924, $2F6F7C87, $58684C11, $C1611DAB, $B6662D3D, $76DC4190, $01DB7106, $98D220BC, $EFD5102A, $71B18589, $06B6B51F, $9FBFE4A5, $E8B8D433, $7807C9A2, $0F00F934, $9609A88E, $E10E9818, $7F6A0DBB, $086D3D2D, $91646C97, $E6635C01, $6B6B51F4, $1C6C6162, $856530D8, $F262004E, $6C0695ED, $1B01A57B, $8208F4C1, $F50FC457, $65B0D9C6, $12B7E950, $8BBEB8EA, $FCB9887C, $62DD1DDF, $15DA2D49, $8CD37CF3, $FBD44C65, $4DB26158, $3AB551CE, $A3BC0074, $D4BB30E2, $4ADFA541, $3DD895D7, $A4D1C46D, $D3D6F4FB, $4369E96A, $346ED9FC, $AD678846, $DA60B8D0, $44042D73, $33031DE5, $AA0A4C5F, $DD0D7CC9, $5005713C, $270241AA, $BE0B1010, $C90C2086, $5768B525, $206F85B3, $B966D409, $CE61E49F, $5EDEF90E, $29D9C998, $B0D09822, $C7D7A8B4, $59B33D17, $2EB40D81, $B7BD5C3B, $C0BA6CAD, $EDB88320, $9ABFB3B6, $03B6E20C, $74B1D29A, $EAD54739, $9DD277AF, $04DB2615, $73DC1683, $E3630B12, $94643B84, $0D6D6A3E, $7A6A5AA8, $E40ECF0B, $9309FF9D, $0A00AE27, $7D079EB1, $F00F9344, $8708A3D2, $1E01F268, $6906C2FE, $F762575D, $806567CB, $196C3671, $6E6B06E7, $FED41B76, $89D32BE0, $10DA7A5A, $67DD4ACC, $F9B9DF6F, $8EBEEFF9, $17B7BE43, $60B08ED5, $D6D6A3E8, $A1D1937E, $38D8C2C4, $4FDFF252, $D1BB67F1, $A6BC5767, $3FB506DD, $48B2364B, $D80D2BDA, $AF0A1B4C, $36034AF6, $41047A60, $DF60EFC3, $A867DF55, $316E8EEF, $4669BE79, $CB61B38C, $BC66831A, $256FD2A0, $5268E236, $CC0C7795, $BB0B4703, $220216B9, $5505262F, $C5BA3BBE, $B2BD0B28, $2BB45A92, $5CB36A04, $C2D7FFA7, $B5D0CF31, $2CD99E8B, $5BDEAE1D, $9B64C2B0, $EC63F226, $756AA39C, $026D930A, $9C0906A9, $EB0E363F, $72076785, $05005713, $95BF4A82, $E2B87A14, $7BB12BAE, $0CB61B38, $92D28E9B, $E5D5BE0D, $7CDCEFB7, $0BDBDF21, $86D3D2D4, $F1D4E242, $68DDB3F8, $1FDA836E, $81BE16CD, $F6B9265B, $6FB077E1, $18B74777, $88085AE6, $FF0F6A70, $66063BCA, $11010B5C, $8F659EFF, $F862AE69, $616BFFD3, $166CCF45, $A00AE278, $D70DD2EE, $4E048354, $3903B3C2, $A7672661, $D06016F7, $4969474D, $3E6E77DB, $AED16A4A, $D9D65ADC, $40DF0B66, $37D83BF0, $A9BCAE53, $DEBB9EC5, $47B2CF7F, $30B5FFE9, $BDBDF21C, $CABAC28A, $53B39330, $24B4A3A6, $BAD03605, $CDD70693, $54DE5729, $23D967BF, $B3667A2E, $C4614AB8, $5D681B02, $2A6F2B94, $B40BBE37, $C30C8EA1, $5A05DF1B, $2D02EF8D); (* function CRC32(CRC: LongWord; Data: Pointer; DataSize: LongWord): LongWord; assembler; asm AND EDX,EDX JZ @Exit AND ECX,ECX JLE @Exit PUSH EBX PUSH EDI XOR EBX,EBX LEA EDI,CS:[OFFSET @CRC32] @Start: MOV BL,AL SHR EAX,8 XOR BL,[EDX] XOR EAX,[EDI + EBX * 4] INC EDX DEC ECX JNZ @Start POP EDI POP EBX @Exit: RET DB 0, 0, 0, 0, 0 // Align Table @CRC32: DD 000000000h, 077073096h, 0EE0E612Ch, 0990951BAh DD 0076DC419h, 0706AF48Fh, 0E963A535h, 09E6495A3h DD 00EDB8832h, 079DCB8A4h, 0E0D5E91Eh, 097D2D988h DD 009B64C2Bh, 07EB17CBDh, 0E7B82D07h, 090BF1D91h DD 01DB71064h, 06AB020F2h, 0F3B97148h, 084BE41DEh DD 01ADAD47Dh, 06DDDE4EBh, 0F4D4B551h, 083D385C7h DD 0136C9856h, 0646BA8C0h, 0FD62F97Ah, 08A65C9ECh DD 014015C4Fh, 063066CD9h, 0FA0F3D63h, 08D080DF5h DD 03B6E20C8h, 04C69105Eh, 0D56041E4h, 0A2677172h DD 03C03E4D1h, 04B04D447h, 0D20D85FDh, 0A50AB56Bh DD 035B5A8FAh, 042B2986Ch, 0DBBBC9D6h, 0ACBCF940h DD 032D86CE3h, 045DF5C75h, 0DCD60DCFh, 0ABD13D59h DD 026D930ACh, 051DE003Ah, 0C8D75180h, 0BFD06116h DD 021B4F4B5h, 056B3C423h, 0CFBA9599h, 0B8BDA50Fh DD 02802B89Eh, 05F058808h, 0C60CD9B2h, 0B10BE924h DD 02F6F7C87h, 058684C11h, 0C1611DABh, 0B6662D3Dh DD 076DC4190h, 001DB7106h, 098D220BCh, 0EFD5102Ah DD 071B18589h, 006B6B51Fh, 09FBFE4A5h, 0E8B8D433h DD 07807C9A2h, 00F00F934h, 09609A88Eh, 0E10E9818h DD 07F6A0DBBh, 0086D3D2Dh, 091646C97h, 0E6635C01h DD 06B6B51F4h, 01C6C6162h, 0856530D8h, 0F262004Eh DD 06C0695EDh, 01B01A57Bh, 08208F4C1h, 0F50FC457h DD 065B0D9C6h, 012B7E950h, 08BBEB8EAh, 0FCB9887Ch DD 062DD1DDFh, 015DA2D49h, 08CD37CF3h, 0FBD44C65h DD 04DB26158h, 03AB551CEh, 0A3BC0074h, 0D4BB30E2h DD 04ADFA541h, 03DD895D7h, 0A4D1C46Dh, 0D3D6F4FBh DD 04369E96Ah, 0346ED9FCh, 0AD678846h, 0DA60B8D0h DD 044042D73h, 033031DE5h, 0AA0A4C5Fh, 0DD0D7CC9h DD 05005713Ch, 0270241AAh, 0BE0B1010h, 0C90C2086h DD 05768B525h, 0206F85B3h, 0B966D409h, 0CE61E49Fh DD 05EDEF90Eh, 029D9C998h, 0B0D09822h, 0C7D7A8B4h DD 059B33D17h, 02EB40D81h, 0B7BD5C3Bh, 0C0BA6CADh DD 0EDB88320h, 09ABFB3B6h, 003B6E20Ch, 074B1D29Ah DD 0EAD54739h, 09DD277AFh, 004DB2615h, 073DC1683h DD 0E3630B12h, 094643B84h, 00D6D6A3Eh, 07A6A5AA8h DD 0E40ECF0Bh, 09309FF9Dh, 00A00AE27h, 07D079EB1h DD 0F00F9344h, 08708A3D2h, 01E01F268h, 06906C2FEh DD 0F762575Dh, 0806567CBh, 0196C3671h, 06E6B06E7h DD 0FED41B76h, 089D32BE0h, 010DA7A5Ah, 067DD4ACCh DD 0F9B9DF6Fh, 08EBEEFF9h, 017B7BE43h, 060B08ED5h DD 0D6D6A3E8h, 0A1D1937Eh, 038D8C2C4h, 04FDFF252h DD 0D1BB67F1h, 0A6BC5767h, 03FB506DDh, 048B2364Bh DD 0D80D2BDAh, 0AF0A1B4Ch, 036034AF6h, 041047A60h DD 0DF60EFC3h, 0A867DF55h, 0316E8EEFh, 04669BE79h DD 0CB61B38Ch, 0BC66831Ah, 0256FD2A0h, 05268E236h DD 0CC0C7795h, 0BB0B4703h, 0220216B9h, 05505262Fh DD 0C5BA3BBEh, 0B2BD0B28h, 02BB45A92h, 05CB36A04h DD 0C2D7FFA7h, 0B5D0CF31h, 02CD99E8Bh, 05BDEAE1Dh DD 09B64C2B0h, 0EC63F226h, 0756AA39Ch, 0026D930Ah DD 09C0906A9h, 0EB0E363Fh, 072076785h, 005005713h DD 095BF4A82h, 0E2B87A14h, 07BB12BAEh, 00CB61B38h DD 092D28E9Bh, 0E5D5BE0Dh, 07CDCEFB7h, 00BDBDF21h DD 086D3D2D4h, 0F1D4E242h, 068DDB3F8h, 01FDA836Eh DD 081BE16CDh, 0F6B9265Bh, 06FB077E1h, 018B74777h DD 088085AE6h, 0FF0F6A70h, 066063BCAh, 011010B5Ch DD 08F659EFFh, 0F862AE69h, 0616BFFD3h, 0166CCF45h DD 0A00AE278h, 0D70DD2EEh, 04E048354h, 03903B3C2h DD 0A7672661h, 0D06016F7h, 04969474Dh, 03E6E77DBh DD 0AED16A4Ah, 0D9D65ADCh, 040DF0B66h, 037D83BF0h DD 0A9BCAE53h, 0DEBB9EC5h, 047B2CF7Fh, 030B5FFE9h DD 0BDBDF21Ch, 0CABAC28Ah, 053B39330h, 024B4A3A6h DD 0BAD03605h, 0CDD70693h, 054DE5729h, 023D967BFh DD 0B3667A2Eh, 0C4614AB8h, 05D681B02h, 02A6F2B94h DD 0B40BBE37h, 0C30C8EA1h, 05A05DF1Bh, 02D02EF8Dh DD 074726F50h, 0736E6F69h, 0706F4320h, 067697279h DD 028207468h, 031202963h, 020393939h, 048207962h DD 06E656761h, 064655220h, 06E616D64h, 06FBBA36Eh end; *) procedure CalcCRC32(Data: Pointer; DataSize: DWord; var CRCValue: DWord); // The following is a little cryptic (but executes very quickly). // The algorithm is as follows: // 1. exclusive-or the input byte with the low-order byte of // the CRC register to get an INDEX // 2. shift the CRC register eight bits to the right // 3. exclusive-or the CRC register with the contents of Table[INDEX] // 4. repeat steps 1 through 3 for all bytes var i: Integer; q: ^Byte; begin q := Data; if DataSize = 0 then exit; for i := 0 to DataSize - 1 do begin CRCValue := (CRCValue SHR 8) XOR CRC32Table[q^ XOR (CRCValue AND $000000FF)]; Inc(q); end; end; {a Random generated Testvector 256bit - 32 Bytes, it's used for Self Test} { function GetTestVector: PAnsiChar; assembler; register; asm MOV EAX,OFFSET @Vector RET @Vector: DB 030h,044h,0EDh,06Eh,045h,0A4h,096h,0F5h DB 0F6h,035h,0A2h,0EBh,03Dh,01Ah,05Dh,0D6h DB 0CBh,01Dh,009h,082h,02Dh,0BDh,0F5h,060h DB 0C2h,0B8h,058h,0A1h,091h,0F9h,081h,0B1h DB 000h,000h,000h,000h,000h,000h,000h,000h end; } var TableCRC: DWord; initialization {this calculate a Checksum (CRC32) over the function CRC32 and the TestVector, if InitTestIsOk = False any modification from Testvector or CRC32() detected, :-) } TableCRC := $FFFFFFFF; CalcCRC32(@CRC32Table[0], SizeOf(CRC32Table), TableCRC); TableCRC := not TableCRC; if TableCRC <> $6FCF9E13 then raise Exception.Create('Bad case, wrong CRC table'); finalization end.