Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Spezielles CRC-16: Übersetzung aus C++ (omg) (https://www.delphipraxis.net/112000-spezielles-crc-16-uebersetzung-aus-c-omg.html)

blackdrake 13. Apr 2008 02:37


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:
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 Versuch (total Fehlerhaft):

Delphi-Quellcode:
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;
Ich wäre sehr froh, wenn mir jemand helfen könnte.

Gruß
blackdrake

Namenloser 13. Apr 2008 03:27

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 Wikipediaartikel. Dort findet sich zwar auch C-Quellcode aber auch noch ein Pseudocode in verständlicher Sprache :zwinker:

Muetze1 13. Apr 2008 16:39

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:
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:
/EDIT: Fehler korrigiert

blackdrake 13. Apr 2008 20:19

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:
Automatic save #1
Initial value:   196
Iteration:       1594
Number of digits: 660
2233391095887226489252669400293097928968313993852178183738667668494442
9492212526384486180648256622642810060306066783863577455348324982112153
2715135808841488252902869804477229097398710010629119577823823636994210
4216172688309063196431367011997341372581744233400975666507297914430210
4906519900706600977758820709608947205935274463095556013643625406027389
1590711796777899560809902460840131235188036946665800933324481763731427
0021076313459127091279618161151123907253294177760209360100069046919128
7439796929935178513890764052723512111805228535536862593777696129500193
4622665174708257449461421230482444959667668273817821493904138589288012
820049673518847316886010834312
Die CRC-16 Werte mit abschließendem #13#10:

Original: 59F6
Delphi: DFD4

Die CRC-16 Werte ohne abschließendem #13#10:

Original: 470E
Delphi: 358E

3_of_8 13. Apr 2008 21:08

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: http://andorra.cvs.sourceforge.net/a...C.pas?view=log)

blackdrake 13. Apr 2008 21:32

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

Dezipaitor 13. Apr 2008 22:05

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: http://rvelthuis.de/articles/articles-cobjs.html

Muetze1 14. Apr 2008 00:29

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.

gammatester 14. Apr 2008 10:49

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 (http://filext.com/file-extension/ISF listet einige), aber der C++ Code öffnet sie binär.

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

Muetze1 14. Apr 2008 10:52

Re: Spezielles CRC-16: Übersetzung aus C++ (omg)
 
Zitat:

Zitat von gammatester
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.

Nein, "Initial value" wird schon mit einberechnet, da "Automatic save #1" schon zwei Leerzeichen hat. Er fängt also die CRC Berechnung mit dem "#" von "#1" an.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:16 Uhr.
Seite 1 von 2  1 2      

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