unit uCRC16;
interface
uses
Winapi.Windows,
Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.StdCtrls,
Vcl.ExtCtrls;
type
TForm1 =
class(TForm)
LabeledEdit1: TLabeledEdit;
LabeledEdit2: TLabeledEdit;
Button1: TButton;
Button2: TButton;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Function CalcCRC16(
const Buffer:
array of byte) : Word;
const
Mask: Word = $A001;
var
CRC: Word;
N, I: Integer;
B: Byte;
begin
CRC := $FFFF;
for I := Low(Buffer)
to High(Buffer)
do
begin
B := Buffer[I];
CRC := CRC
xor B;
for N := 1
to 8
do
if (CRC
and 1) > 0
then
CRC := (CRC
shr 1)
xor Mask
else
CRC := (CRC
shr 1);
end;
Result := CRC;
// Result := (IntToHex(CRC, 4)); (* Ausgabe *)
end;
function FileCRC16(
const FileName:
string;
var CRC16: Word; StartPos: Int64 = 0;
Len: Int64 = 0): Boolean;
const
csBuff_Size = 4096;
type
TBuff =
array[0..csBuff_Size - 1]
of Byte;
var
Handle: THandle;
ReadCount: Integer;
Size: Int64;
Count: Int64;
Buff: TBuff;
begin
Handle := CreateFile(PChar(FileName), GENERIC_READ,
FILE_SHARE_READ,
nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
Result :=
Handle <> INVALID_HANDLE_VALUE;
if Result
then
try
Int64Rec(Size).Lo := GetFileSize(
Handle, @Int64Rec(Size).Hi);
if Size < StartPos + Len
then
begin
Result := False;
Exit;
end;
if Len > 0
then
Count := Len
else
Count := Size - StartPos;
CRC16 :=
not CRC16;
SetFilePointer(
Handle, Int64Rec(StartPos).Lo, @Int64Rec(StartPos).Hi, FILE_BEGIN);
while Count > 0
do
begin
if Count > SizeOf(Buff)
then
ReadCount := SizeOf(Buff)
else
ReadCount := Count;
ReadFile(
Handle, Buff, ReadCount, LongWord(ReadCount),
nil);
CRC16 := CalcCRC16(Buff);
Dec(Count, ReadCount);
end;
CRC16 :=
not CRC16;
finally
CloseHandle(
Handle);
end;
end;
// Hier wird CRC16 einer Datei Berechnet
procedure TForm1.Button1Click(Sender: TObject);
var
CRC16: Word;
begin
CRC16 := 0;
if OpenDialog1.Execute
then
begin
if FileCRC16(OpenDialog1.FileName, CRC16)
then
LabeledEdit2.Text := (IntToHex(CRC16, 4));
end;
end;
// Hier wird CRC16 eines Strings Berechnet
procedure TForm1.Button2Click(Sender: TObject);
var
s:
String;
buff:
packed array of byte;
i: Integer;
begin
s := LabeledEdit1.Text;
SetLength(buff, Length(s));
for i := 0
to (Length(s))-1
do buff[i] := Byte(Ord(s[i+1]));
LabeledEdit2.Text := (IntToHex(CalcCRC16(buff), 4));
end;
end.