![]() |
Spezielles CRC-16: Übersetzung aus C++ (omg)
Hallo.
Ich möchte folgenden Code von C++ nach Delphi übersetzen. Leider habe ich kaum Ahnung von der exakten Funktionsweise dieser Codestelle. Es soll eine spezielle Prüfsumme aus einer Datei gelesen werden. Die Datei kenne ich, die zu erwartende Prüfsumme auch. Ich kann aus dem Originalcode aber nicht mal erkennen, ab wann gelesen wird (was bedeutet z.B. "größer-gleich Leerzeichen"?). C++:
Code:
Delphi Versuch (total Fehlerhaft):
unsigned short crc16(unsigned char data, unsigned short poly, unsigned short resl)
// Appends one byte to a runing CRC-16 calculation { int i; resl^=(unsigned short)(((unsigned short)data)<<8); for(i=8;i>0;--i) { if(resl&0x8000) resl=(unsigned short)((resl<<1)^poly); else resl=(unsigned short)((resl<<1)); } return (resl); } unsigned short file_crc16(char *fnam) // Calculates the CRC-16 of the ISF file { FILE *finp; unsigned char crcd; unsigned short crcr; if((finp=fopen(fnam,"rb"))==NULL) return(0xFFFF); crcd='0'; crcr=0xFFFF; while((fread(&crcd,1,1,finp)==1)&&(crcd>=' ')); while((fread(&crcd,1,1,finp)==1)&&(crcd>=' ')); while(fread(&crcd,1,1,finp)==1) crcr=crc16(crcd, 0x1021, crcr); fclose(finp); return(crcr); }
Delphi-Quellcode:
Ich wäre sehr froh, wenn mir jemand helfen könnte.
function my_crc16(data: char; poly, resl: short): short;
var i: integer; begin resl := resl xor (ord(data) shl 8); for i := 8 downto 1 do begin if (resl and $8000) = $8000 then begin resl := (resl shl 1) xor poly; end else begin resl := resl shl 1; end; end; result := resl; end; procedure TForm2.Button1Click(Sender: TObject); var erg: integer; i: integer; tmp: string; begin erg := $FFFF; for i := 1 to length(memo1.text) - 1 do begin tmp := copy(memo1.text, i, 1); erg := ord(tmp[1]); erg := my_crc16(chr(erg), $1021, erg); end; showmessage(inttohex(erg, 4)); end; Gruß blackdrake |
Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
Hallo.
Ich kenne mich mit der C++-Syntax auch nicht gerade sehr gut aus, aber vielleicht hilft dir ja der ![]() |
Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
Einfach hier im Beitragseditor getippt, also wohl noch ein paar syntaktische Fehler drin. Ansonsten stur übersetzt, samt der manchmal unnötigen Typecasts.
Delphi-Quellcode:
/EDIT: Fehler korrigiert
function crc16(const AData: Char; APoly, AResult: word): word;
// Appends one byte to a runing CRC-16 calculation var i: integer; begin AResult := AResult xor word(word(AData) shl 8)); for i := 1 to 8 do begin if ( AResult and $8000 ) <> 0 then AResult := (AResult shl 1) xor APoly else AResult := AResult shl 1; end; result := AResult; end; function file_crc16(const AFilename: string): word; // Calculates the CRC-16 of the ISF file var lFile: TStream; // finp lData: Char; // crcd lCRC: Word; // crcr begin lCRC := $ffff; try lFile := TFileStream.Create(AFilename, fmOpenRead); try lData := '0'; while ( lFile.Read(lData, 1) = 1 ) and ( lData >= ' ' ) do ; while ( lFile.Read(lData, 1) = 1 ) and ( lData >= ' ' ) do ; while ( lFile.Read(lData, 1) = 1 ) do lCRC := crc16(lData, $1021, lCRC); finally lFile.Free; end; except ; // böse..., aber original hat auch keine Exceptions geworfen... end; result := lCRC; end: |
Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
Hallo.
Vielen Dank für die Übersetzung! Ich verstehe die Codestellen jetzt etwas besser. Auf jeden Fall habe ich jetzt zumindestens herausgefunden, dass die 2 >='' einen Start ab "Initial value" bezweckt. Leider funktioniert der Code nicht so wie im Original, obwohl es theoretisch gleich sein müsste. Weißt du, wo das Problem liegen könnte? Hier eine ISF-Datei
Code:
Die CRC-16 Werte mit abschließendem #13#10:
Automatic save #1
Initial value: 196 Iteration: 1594 Number of digits: 660 2233391095887226489252669400293097928968313993852178183738667668494442 9492212526384486180648256622642810060306066783863577455348324982112153 2715135808841488252902869804477229097398710010629119577823823636994210 4216172688309063196431367011997341372581744233400975666507297914430210 4906519900706600977758820709608947205935274463095556013643625406027389 1590711796777899560809902460840131235188036946665800933324481763731427 0021076313459127091279618161151123907253294177760209360100069046919128 7439796929935178513890764052723512111805228535536862593777696129500193 4622665174708257449461421230482444959667668273817821493904138589288012 820049673518847316886010834312 Original: 59F6 Delphi: DFD4 Die CRC-16 Werte ohne abschließendem #13#10: Original: 470E Delphi: 358E |
Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
Ich bin mir nicht sicher, wie der CRC-16 da funktioniert, aber du könntest es mit der von mir geschriebenen AdCRC.pas hinbekommen. Probier mal aus, was rauskommt, wen du einfach die beiden LSBs aus dem CRC32, den ich berechne, rauspickst.
(Link: ![]() |
Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
Hallo.
Danke für den Hinweis. Aber hier scheint es sich um einen sehr speziellen CRC zu handeln. (Ich habe die Erfahrung machen müssen, dass es keine Einheitlichen CRC16/32 gibt, siehe ModBus und alternierende Startwerte) Es wird außerdem Zeichen für Zeichen berechnet. Deswegen möchte ich beim Originalcode bleiben. Gruß blackdrake |
Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
Du kannst auch einfach den C Code in eine OBJ Datei kompilieren und dann diese in Delphi einbinden. Dann musst du nur noch die Funktionsköpfe nach Delphi konvertieren.
Rudy hat einen Artikel darüber geschrieben: ![]() |
Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
Ich habe bei dem Code zuvor eigenmächtig eine Optimierung gemacht, die aber zu einem falschen Ergebnis führt. Von daher habe ich oben den Code korrigiert. Bitte den Code erneut ausprobieren.
|
Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
Das CRC-Polynom ist das altbekannte CRC-16-CCITT (Dein Code benutzt den Startwert $FFFF statt wie meist $0000); das bedeutet auch, daß 3_of_8's Hinweis nicht zum Erfolg führen wird.
Ich weiß zwar nicht, was ISF-Files sind ( ![]() Allerdings scheint mit der Code nicht sehr sinnvoll, da erstmal zwei Blöcke mit Zeichen >= ' ' überlesen werden. Wenn man die Beispieldatei wörtlich nimmt, würden also Automatic save #1 und Initial value: 196 überlesen und die CRC-Berechnung startet mit dem #13#10 danach. Also: erstmal klären worüber genau der CRC berechnet werden soll. Gruß Gammatester |
Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:16 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