Recently, crc8 verification is required for a program. I found a bunch of data on the Internet and felt dizzy. I still don't understand the algorithm. Finally, I found a C source code. Please translate it into Delphi to solve the problem. Thank you for your attention .. The Delphi program he wrote is as follows:
// ****** Lanyus *******//
Original C program:
The original C program is as follows:
/* CRC Check (8n )*/
Unsigned char crc_8n (unsigned char * PTR, unsigned char N)
{
Unsigned char J = 8;
Unsigned char cbit, out;
Unsigned char CRC = 0, crc_a = 0, crc_ B = 0;
/* Take the shifted bit */
Toggle_wd ();
Do {
Crc_a = * PTR;
PTR ++;
J = 8;
Cbit = 1;
Do {
Crc_ B = crc_a;
Crc_ B = crc_ B ^ CRC;
Out = crc_ B & cbit;
// Crc_ B = crc_ B> 1;
If (OUT! = 0)
{
CRC = CRC ^ 0x18;
CRC = CRC> 1;
CRC | = 0x80;
} Else
CRC = CRC> 1;
Crc_a = crc_a> 1;
// Cbit = cbit <1;
} While (-- J );
} While (-- N );
Toggle_wd ();
Return CRC;
}
Delphi translation version:
Unit crc8;
Interface
Uses
Classes, windows;
Function crc_8n (P: array of byte; Len: byte): byte;
Implementation
Function crc_8n (P: array of byte; Len: byte): byte;
VaR
J, cbit, aout, CRC, crc_a, crc_ B: byte;
I: integer;
Begin
CRC: = 0;
I: = 0;
// Take the shifted bit
Repeat
Crc_a: = P [I];
INC (I );
J: = 8;
Cbit: = 1;
Repeat
Crc_ B: = crc_a;
Crc_ B: = crc_ B XOR CRC ;//?????
Aout: = crc_ B and cbit;
If aout <> 0 then begin
CRC: = crc xor $18 ;//?????
CRC: = crc shr 1;
CRC: = CRC or $80;
End else begin
CRC: = crc shr 1;
End;
Crc_a: = crc_a SHR 1;
Dec (j );
Until J = 0;
Dec (LEN );
Until Len = 0;
Result: = CRC;
End;
End.
======================================
Unit Main;
Interface
Uses
Windows, messages, sysutils, variants, classes, graphics, controls, forms,
Dialogs, stdctrls,
Crc8;
Type
Tform1 = Class (tform)
Edit1: tedit;
Memo1: tmemo;
Button1: tbutton;
Procedure button1click (Sender: tobject );
Private
{Private Declarations}
Public
{Public declarations}
End;
VaR
Form1: tform1;
Implementation
{$ R *. DFM}
Const minbase = 2;
Maxbase = 36;
Function strtonum (const S: string; base: integer;
Neg: Boolean; max: integer): integer;
// S = string to be converted
// Base = base number
// Neg = whether it is a negative number
// Max = the maximum number to be converted //
// Usage:
// I: = strtonum ('000000', 2, false, maxint );
// I: = strtonum (''002d '', 16, false, maxint );
// I: = strtonum (''-45'', 10, true, maxint );
// I: = strtonum (''zz '', 36, true, maxint );
//
VaR negate, done: Boolean;
I, Len, digit, MMB: integer;
C: Char;
Mdb, Res: integer;
Begin
Res: = 0; I: = 1; digit: = 0;
If (base> = minbase) and (base <= maxbase) then begin
MMB: = max mod base;
MDB: = max Div base;
Len: = length (s );
Negate: = false;
While (I <= Len) and (S [I] = '') Do Inc (I );
If neg then begin
Case s [I]
'+': Inc (I );
'-': Begin Inc (I); negate: = true; end;
End; (* case *)
End; (* If neg *)
Done: = Len> I;
While (I <= Len) and done do begin
C: = upcase (s [I]);
Case C
'0' .. '9': digit: = ord (c)-48;
'A' .. 'Z': digit: = ord (c)-55;
Else done: = false
End; (* case *)
Done: = Done And (digit <base );
If done then begin
Done: = (RES <MDB) or (RES = MDB) and (digit <= MMB ));
If done then begin
Res: = res * base + digit;
INC (I );
End; (* if done *)
End; (* if done *)
End; (* While *)
If negate then res: =-res;
End; (* if done *)
Result: = res;
End;
Procedure tform1.button1click (Sender: tobject );
VaR
S: string;
P: array [0 .. 255] of byte;
Len: byte;
R: byte;
I: integer;
Begin
S: = edit1.text;
If length (s) mod 2 = 1 then s: = S + '0 ';
Memo1.lines. Add (S + ':');
For I: = 1 to length (s) Div 2 do begin
P [I-1]: = byte (strtonum (copy (S, (I-1) * 2 + 1, 2), 16, false, 500 ));
Memo1.lines. Add (inttostr (I) + '-->' + inttohex (P [I-1], 2 ));
End;
Len: = length (s) Div 2;
R: = crc_8n (p, Len );
Memo1.lines. Add ('crc8 result: '+ inttohex (R, 2 ));
End;
End.