-
Notifications
You must be signed in to change notification settings - Fork 1
/
CRCunit.pas
87 lines (77 loc) · 1.66 KB
/
CRCunit.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
unit CRCunit;
interface
function GetNewCRC(OldCRC: cardinal; StPtr: pointer; StLen: integer): cardinal;
procedure UpdateCRC(StPtr: pointer; StLen: integer; var CRC: cardinal);
function GetZipCRC(StPtr: pointer; StLen: integer): cardinal;
function GetFileCRC(const FileName: string): cardinal;
implementation
var
CRCtable: array[0..255] of cardinal;
function GetNewCRC(OldCRC: cardinal; StPtr: pointer; StLen: integer): cardinal;
asm
test edx,edx;
jz @ret;
neg ecx;
jz @ret;
sub edx,ecx; // Address after last element
push ebx;
mov ebx,0; // Set ebx=0 & align @next
@next:
mov bl,al;
xor bl,byte [edx+ecx];
shr eax,8;
xor eax,cardinal [CRCtable+ebx*4];
inc ecx;
jnz @next;
pop ebx;
@ret:
end;
procedure UpdateCRC(StPtr: pointer; StLen: integer; var CRC: cardinal);
begin
CRC := GetNewCRC(CRC, StPtr, StLen);
end;
function GetZipCRC(StPtr: pointer; StLen: integer): cardinal;
begin
Result := not GetNewCRC($FFFFFFFF, StPtr, StLen);
end;
function GetFileCRC(const FileName: string): cardinal;
const
BufSize = 64 * 1024;
var
Fi: file;
pBuf: PChar;
Count: integer;
begin
Assign(Fi, FileName);
Reset(Fi, 1);
GetMem(pBuf, BufSize);
Result := $FFFFFFFF;
repeat
BlockRead(Fi, pBuf^, BufSize, Count);
if Count = 0 then
break;
Result := GetNewCRC(Result, pBuf, Count);
until false;
Result := not Result;
FreeMem(pBuf);
CloseFile(Fi);
end;
procedure CRCInit;
var
c: cardinal;
i, j: integer;
begin
for i := 0 to 255 do
begin
c := i;
for j := 1 to 8 do
if odd(c) then
c := (c shr 1) xor $EDB88320
else
c := (c shr 1);
CRCtable[i] := c;
end;
end;
initialization
CRCinit;
end.