![]() |
AW: CRC von C in Delphi übersetze
Folgendes Programm liefert bei mir das korrekt Ergebnis
Delphi-Quellcode:
program CRCTest;
{$APPTYPE CONSOLE} {$R *.res} uses SysUtils; function cal_crc_half(pin: PByte; len: Byte): Word; var crc: Word; da: Byte; ptr: PByte; bCRCHign: Byte; bCRCLow: Byte; const crc_ta: array[0..15] of Word = ($0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7, $8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef); begin ptr := pin; crc := 0; while (len > 0) do begin da := crc shr 12; // CRC high four bits crc := crc shl 4; // The CRC is shifted to the right by 4 bits, which is equivalent to taking the lower 12 bits of the CRC. crc := crc xor crc_ta[da xor (ptr^ shr 4)]; // Add the upper 4 bits of the CRC and the first half of the byte and look up the table to calculate the CRC, then add the remainder of the last CRC. da := crc shr 12; // CRC high four bits crc := crc shl 4; // The CRC is shifted to the right by 4 bits, which is equivalent to taking the lower 12 bits of the CRC. crc := crc xor crc_ta[da xor (ptr^ and $0f)]; // Add the upper 4 bits of the CRC and the last half of the byte and look up the table to calculate the CRC, then add the remainder of the last CRC. Inc(ptr); Dec(len); end; bCRCLow := crc and $FF; bCRCHign := crc shr 8; if (bCRCLow = $28) or (bCRCLow = $0d) or (bCRCLow = $0a) then Inc(bCRCLow); if (bCRCHign = $28) or (bCRCHign = $0d) or (bCRCHign = $0a) then Inc(bCRCHign); crc := (bCRCHign shl 8) + bCRCLow; Result := crc; end; var Test: AnsiString; CRC: Word; begin try Test := 'QPIGS'; CRC := cal_crc_half(Pointer(Test), Length(Test)); writeln(IntToHex(CRC, 4)); ReadLn; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
AW: CRC von C in Delphi übersetze
Zitat:
Delphi-Quellcode:
Die Übersetzung ist nahe am C-Code und bestätigt die Doku:
{$R-}
function CalcCRC(const pmcText: AnsiString): Word; const CRC_TABLE: array[0..15] of Word = ( $0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7, $8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef); var p: PAnsiChar; crc: Word; tbl: Byte; crcLo: Byte; crcHi: Byte; begin if pmcText = '' then Exit(0); //=> crc := 0; p := Pointer(pmcText); while p^ <> #0 do begin tbl := crc shr 12; crc := crc shl 4; crc := crc xor CRC_TABLE[tbl xor (Ord(p^) shr 4)]; tbl := crc shr 12; crc := crc shl 4; crc := crc xor CRC_TABLE[tbl xor (Ord(p^) and $0f)]; Inc(p); end; crcLo := crc and $ff; crcHi := crc shr 8; if (crcLo = $28) or (crcLo = $0d) or (crcLo = $0a) then Inc(crcLo); if (crcHi = $28) or (crcHi = $0d) or (crcHi = $0a) then Inc(crcHi); crc := (crcHi shl 8) + crcLo; Result := crc; end; {$R+}
Delphi-Quellcode:
Bis bald...
var
txt: AnsiString; begin txt := 'QPIGS'; ShowMessage(CalcCRC(txt).ToHexString(4)); // => $B7A9 Thomas |
AW: CRC von C in Delphi übersetze
Guten Morgen!
sorry - am Freitag spät Abends war ich platt, aber ich hatte eine Lösung! Diese Seite hat mich auf die richtige Spur gebracht: ![]() Es handelt sich bei meiner Aufgabe um ein CCITT XMODEM CRC. So habe ich es dann gelöst:
Delphi-Quellcode:
Meinen ausdrücklichen Dank an alle Helfer hier!
function CAL_CRC_CCITT_XMODEM(data: PByte; len: Integer): Word;
const poly = $1021; var i, j: Integer; crc: Word; begin crc := 0; for i := 0 to len-1 do begin crc := crc xor (Word(data^) shl 8); for j := 0 to 7 do begin if (crc and $8000) > 0 then crc := (crc shl 1) xor poly else crc := crc shl 1; end; Inc(data); end; Result := crc; end; Es ist wirklich schön zu wissen, dass man nach Hilfe fragen kann und diese auch bekommt. Danke! Gruß und und eine schöne Woche Markus |
AW: CRC von C in Delphi übersetze
Zitat:
Zitat:
Delphi-Quellcode:
Teste deine Version mal gegen das C-Original für folgende Eingaben: YO, ZOL, DIHN, VRY77, PK20OM, 6A07EBH
{$R-}
function CalcCRC(pmPText: PAnsiChar): Word; const CRC_TABLE: array[0..15] of Word = ( $0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7, $8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef); var idx: Byte; crc: WordRec absolute Result; begin Result := 0; if pmPText = Nil then Exit; //=> while pmPText^ <> #0 do begin idx := (Result shr 12) xor (Ord(pmPText^) shr 4); Result := (Result shl 4) xor CRC_TABLE[idx]; idx := (Result shr 12) xor (Ord(pmPText^) and $0f); Result := (Result shl 4) xor CRC_TABLE[idx]; Inc(pmPText); end; if (crc.Lo = $28) or (crc.Lo = $0d) or (crc.Lo = $0a) then Inc(crc.Lo); if (crc.Hi = $28) or (crc.Hi = $0d) or (crc.Hi = $0a) then Inc(crc.Hi); end; {$R+} var txt: AnsiString; begin for var i: Integer := 0 to 1000000 do begin txt := TSynTestCase.RandomIdentifier(1 + Random(20)); if CalcCRC(Pointer(txt)) <> CAL_CRC_CCITT_XMODEM(Pointer(txt), Length(txt)) then TSynLog.Add.Log(sllInfo, Utf8ToString(txt)); Bis bald... Thomas |
AW: CRC von C in Delphi übersetze
richtig, das ist NICHT der usrprünglich gepostete Code. Dieser war eine C nach Delphi Übersetzung des Codes aus der Dokumentation des Geräteherstellers.
Das Problem ist, dass die Doku schlicht falsch ist. Der richtige CRC Ansatz ist: Zitat:
Nochmals Dank für die Mühe. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz