AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Spezielles CRC-16: Übersetzung aus C++ (omg)
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von blackdrake · begonnen am 13. Apr 2008 · letzter Beitrag vom 14. Apr 2008
Antwort Antwort
Seite 1 von 2  1 2      
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#1

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

  Alt 13. Apr 2008, 02:37
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
Daniel Marschall
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#2

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

  Alt 13. Apr 2008, 03:27
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
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#3

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

  Alt 13. Apr 2008, 16:39
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
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#4

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

  Alt 13. Apr 2008, 20:19
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
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von 3_of_8
3_of_8

Registriert seit: 22. Mär 2005
Ort: Dingolfing
4.129 Beiträge
 
Turbo Delphi für Win32
 
#5

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

  Alt 13. Apr 2008, 21:08
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)
Manuel Eberl
„The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.“
- Terry Pratchett
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#6

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

  Alt 13. Apr 2008, 21:32
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
Daniel Marschall
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#7

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

  Alt 13. Apr 2008, 22:05
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
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#8

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

  Alt 14. Apr 2008, 00:29
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.
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#9

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

  Alt 14. Apr 2008, 10:49
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
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#10

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

  Alt 14. Apr 2008, 10:52
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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:33 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz