home *** CD-ROM | disk | FTP | other *** search
- {
-
- *** Universal CRC ***
- *** by Filip Skalka, fip@post.cz ***
- *** August 2002 ***
-
- Supported bit width: 8,16,24,32,...,256 (stepped by 8 bits)
-
- Polynom - Direct mathematical formula without msb bit.
- eg. [0,4,5] means x^8+x^5+x^4+x^0
-
- ByteWidth - Width of CRC in bytes. Range : [1,32]
-
- Masked - Fill initial value of CRC by $FF... and xor output value by $FF... too.
-
-
- Usage:
-
- var
- x,y:longword;
- CRC:TCRC;
- CRC8:TCRC8;
- begin
- CRC:=TCRC.Create([0,1,2,4,5,7,8,10,11,12,16,22,23,26],4);
- x:=1;
- y:=0;
- CRC.CalculateCRC(x,y,4);
-
- CRC8:=TCRC8.Create;
- x:=1;
- y:=0;
- CRC8.CalculateCRC(x,y,1);
- end;
-
- }
- unit CRC;
- interface
-
- type
- TPolynom=set of byte;
-
- TCRC=class
- private
- FByteWidth:cardinal;
- FTable:array of byte;
- FMasked:boolean;
- FPolynom:TPolynom;
- protected
- procedure SetMasked(const AValue:boolean);
- public
- constructor Create(const APolynom:TPolynom;const AByteWidth:cardinal);
-
- property ByteWidth:cardinal read FByteWidth;
- property Polynom:TPolynom read FPolynom;
- property Masked:boolean read FMasked write SetMasked;
-
- procedure CalculateCRC(var Buffer;var Result;const BufferSize:integer);
- end;
-
- TCRC8=class(TCRC)
- public
- constructor Create;
- end;
-
- TCRC16=class(TCRC)
- public
- constructor Create;
- end;
-
- TCRC24=class(TCRC)
- public
- constructor Create;
- end;
-
- TCRC32=class(TCRC)
- public
- constructor Create;
- end;
-
- TCTC64=class(TCRC)
- public
- constructor Create;
- end;
-
- implementation
-
- type
- TEntry=array [0..31] of byte;
- PByteArray=^TByteArray;
- TByteArray=array [0..999] of byte;
-
- procedure ReverseBits(var buffer;const Size:longword);
- asm
- push esi
- push edi
-
- mov esi,eax
- lea edi,esi+edx-1
- mov ecx,edx
-
- shr ecx,1
- adc ecx,0
-
- @Loop:
- jecxz @End
- mov al,[esi]
- mov ah,[edi]
-
- mov edx,ecx
- mov ecx,8
-
- @Loop2:
- rcl ah,1
- rcr al,1
- loop @Loop2
- rcl ah,1
-
- mov ecx,edx
-
- mov [esi],al
- mov [edi],ah
-
- inc esi
- dec edi
- loop @Loop
-
- @End:
-
- pop edi
- pop esi
- end;
-
- procedure ShrByOneBit(var buffer;const Size:longword);
- asm
- push edi
-
- mov edi,eax
- mov ecx,edx
-
- jecxz @End
-
- dec ecx
- jecxz @Rest
-
- @Loop:
- mov ax,[edi]
- shr ax,1
- stosb
- loop @Loop
- mov [edi],ah
- jmp @End
-
- @Rest:
- shr byte ptr [edi],1
-
- @End:
-
- pop edi
- end;
-
- procedure ShrByEightBits(var Source,Dest;const Size:longword);
- asm
- push esi
- push edi
-
- lea esi,[eax+1]
- mov edi,edx
-
- mov edx,ecx
- or edx,edx
- jz @End
-
- dec edx
-
- mov ecx,edx
- jecxz @End
-
- shr ecx,2
- rep movsd
-
- mov ecx,edx
- and ecx,3
- rep movsb
-
- mov [edi],cl
-
- @End:
- pop edi
- pop esi
- end;
-
- procedure XorBuffers(var Source,Dest;const Size:longword); overload;
- asm
- push esi
- push edi
-
- mov esi,eax
- mov edi,edx
-
- mov edx,ecx
- shr ecx,2
- jecxz @Rest
-
- @Loop:
- mov eax,[esi]
- xor [edi],eax
- add esi,4
- add edi,4
- loop @Loop
-
- @Rest:
- mov ecx,edx
- and ecx,3
- jecxz @End
-
- @Loop2:
- mov al,[esi]
- xor [edi],al
- inc esi
- inc edi
- loop @Loop2
-
- @End:
-
- pop edi
- pop esi
- end;
-
- procedure XorBuffers(const Source1,Source2;var Dest;const Size:longword); overload;
- asm
- push esi
- push edi
-
- mov esi,eax
- mov edi,ecx
-
- mov ecx,Size
- shr ecx,2
- jecxz @Rest
-
- @Loop:
- mov eax,[esi]
- xor eax,[edx]
- mov [edi],eax
- add esi,4
- add edi,4
- add edx,4
- loop @Loop
-
- @Rest:
- mov ecx,Size
- and ecx,3
- jecxz @End
-
- @Loop2:
- mov al,[esi]
- xor al,[edx]
- mov [edi],al
- inc esi
- inc edi
- inc edx
- loop @Loop2
-
- @End:
-
- pop edi
- pop esi
- end;
-
- procedure BuildTable(const SourcePolynom:TPolynom;var buffer;const ByteCount:cardinal);
- var i,j:integer;
- Polynom:TEntry;
- Value:TEntry;
- ByteArray:PByteArray absolute buffer;
- Offset:cardinal;
- begin
- assert((ByteCount>=1) and (ByteCount<=32),'Invalid ByteCount');
- move(SourcePolynom,Polynom,ByteCount);
- ReverseBits(Polynom,ByteCount);
- Offset:=0;
- for i:=0 to 255 do
- begin
- fillchar(Value,ByteCount,0);
- Value[0]:=i;
- for j:=0 to 7 do if (value[0] and 1)<>0 then
- begin
- ShrByOneBit(Value,ByteCount);
- XorBuffers(Polynom,Value,ByteCount);
- end
- else ShrByOneBit(Value,ByteCount);
- move(Value,ByteArray[Offset],ByteCount);
- inc(Offset,ByteCount);
- end;
- end;
-
- { TCRC }
-
- constructor TCRC.Create(const APolynom: TPolynom;const AByteWidth: cardinal);
- begin
- if (APolynom<>Polynom) or (AByteWidth<>ByteWidth) then
- begin
- setlength(FTable,AByteWidth*256);
- BuildTable(APolynom,FTable,AByteWidth);
- FPolynom:=APolynom;
- FByteWidth:=AByteWidth;
- end;
- end;
-
- procedure TCRC.SetMasked(const AValue: boolean);
- begin
- if AValue<>FMasked then FMasked:=AValue;
- end;
-
- procedure TCRC.CalculateCRC(var Buffer; var Result;const BufferSize:integer);
- var i:integer;
- ByteArray:TByteArray absolute Buffer;
- ValueArray:TEntry;
- TempArray:TEntry;
- begin
- if FMasked then fillchar(ValueArray,ByteWidth,$ff) else fillchar(ValueArray,ByteWidth,0);
- for i:=0 to BufferSize-1 do
- begin
- ShrByEightBits(ValueArray,TempArray,ByteWidth);
- XorBuffers(TempArray,FTable[(ValueArray[0] xor ByteArray[i])*FByteWidth],ValueArray,ByteWidth);
- end;
- if Masked then
- begin
- fillchar(TempArray,ByteWidth,$ff);
- XorBuffers(TempArray,ValueArray,ByteWidth);
- end;
- move(ValueArray,Result,ByteWidth);
- end;
-
- { TCRC8 }
-
- constructor TCRC8.Create;
- begin
- inherited Create([0,1,3,4,7],1);
- end;
-
- { TCRC16 }
-
- constructor TCRC16.Create;
- begin
- inherited Create([0,5,12],2);
- end;
-
- { TCRC24 }
-
- constructor TCRC24.Create;
- begin
- inherited Create([0,1,5,6,23],3);
- end;
-
- { TCRC32 }
-
- constructor TCRC32.Create;
- begin
- inherited Create([0,1,2,4,5,7,8,10,11,12,16,22,23,26],4);
- end;
-
- { TCTC64 }
-
- constructor TCTC64.Create;
- begin
- inherited Create([0,1,4,7,9,10,12,13,17,19,21,22,23,24,27,29,31,32,33,35,37,38,39,40,45,46,47,52,53,54,55,57,62],8);
- end;
-
- {
- CRC8=x8+x5+x4+x0
- CRC8=x8+x7+x4+x3+x1+x0
- CRC12=x12+x11+x3+x2+x1+x0
- CRC16=x16+x12+x5+x0
- CRC24=x24+x23+x6+x5+x1+x0
- CRC32=x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x1+x0
- CRC64=x64+x4+x3+x1+x0
- CRC64=x64+x62+x57+x55+x54+x53+x52+x47+x46+x45+x40+x39+x38+x37+x35+x33+x32+x31+x29+x27+x24+x23+x22+x21+x19+x17+x13+x12+x10+x9+x7+x4+x1+x0
- }
- end.
-