Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi CRC32 mit DEC erzeugt stimmt nicht? (https://www.delphipraxis.net/137622-crc32-mit-dec-erzeugt-stimmt-nicht.html)

BlueStarHH 24. Jul 2009 12:32


CRC32 mit DEC erzeugt stimmt nicht?
 
Hallo,

ich benutze das DEC von Hagen. Ich habe eine Textdatei die nur den String 123456789 enthält. Erzeuge ich mit der folgenden Funktion den CRC32, erhalte ich 340BC6D9.

Delphi-Quellcode:
function CRC32CalcFile(const FileName:String): String;
var
  FS: TFileStream;
begin
  FS := TFileStream.Create(FileName, fmOpenRead);
  try
    result := IntToHex(CRCCalcEx(CRC_32CCITT, FS.Read), 4);
  finally
    FS.Free;
  end;
end;
Wenn ich jedoch mit dieser Funktion mit dem selben String 123456789 den CRC32 erzeuge, erhalte ich CBF43926.

Delphi-Quellcode:
const
  Buf = '123456789';

  result := IntToHex(CRCCalc(CRC_32CCITT, PAnsiChar(Buf)^, Length(Buf)), 4);
Müssten nicht bei beiden Funktionen CBF43926 zurückgegeben werden? Laut den Webseiten http://www.pvlteam.com/doc/crc/testonline.aspx und
http://www.hashsum.com ist CBF43926 der richtige CRC32. Die erste Webseite sagt, dass 340BC6D9 ein CRC32_jamcrc ist. Was muss geändert werden, damit ich auch bei der Datei CBF43926 herausbekomme? Danke!

himitsu 24. Jul 2009 12:45

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
du mußt auch das richtige Polynom zur Berechnung verwenden

also vermutlich statt CRC_32CCITT irgendwas Anderes

am Häufigsten wird einer dieser beiden Polynome verwendet > $EDB88320 oder $04C11DB7
ich weiß jetzt aber nicht, welchem Typ diese in Hagens DEC entsprechen.

[add]
ps: http://www.delphipraxis.net/internal...=991917#991917

BlueStarHH 24. Jul 2009 13:01

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
Zitat:

Zitat von himitsu
du mußt auch das richtige Polynom zur Berechnung verwenden

also vermutlich statt CRC_32CCITT irgendwas

Ich verwende ja in meinen beiden Funktione das selbe Polynom (CRC_32CCITT). Also müsste doch bei meinen beiden Funktionen das selbe rauskommen. CRC_32CCITT ($04C11DB7) stimmt laut verschiedener Webseiten.

himitsu 24. Jul 2009 13:10

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
hmmm, dann stimmt wohl etwas nicht :gruebel:


du weißt, daß Buf in diesem Fall ein UnicodeString ist?
Delphi-Quellcode:
const
  Buf = '123456789';

  result := IntToHex(CRCCalc(CRC_32CCITT, PAnsiChar(Buf)^, Length(Buf)), 4);
also ist Buf bei dir effektiv nur
Delphi-Quellcode:
Buf = AnsiString('1'#0'2'#0'3'#0'4'#0'5');
#wobei PAnsiChar und ein WideString nicht so gut passen und da sollte es eigentlich eine Meldung seitens Delphi geben :gruebel:


versuch mal
Delphi-Quellcode:
const
  Buf: AnsiString = '123456789';

  result := IntToHex(CRCCalc(CRC_32CCITT, PAnsiChar(Buf)^, Length(Buf)), 4);

gammatester 24. Jul 2009 13:15

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
Versuchs mal mit CRC_32 statt CRC_32CCITT.

BlueStarHH 24. Jul 2009 14:05

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
Zitat:

Zitat von himitsu
versuch mal
Delphi-Quellcode:
const
  Buf: AnsiString = '123456789';

  result := IntToHex(CRCCalc(CRC_32CCITT, PAnsiChar(Buf)^, Length(Buf)), 4);

Klappt auch nicht. Beide Funktionen liefern ein anderen CRC. Der CRC vom oberen Code stimmt ja. Nur die CRC32CalcFile aus meinem Eingangspost liefert einen falschen Wert.

BlueStarHH 24. Jul 2009 14:07

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
Zitat:

Zitat von gammatester
Versuchs mal mit CRC_32 statt CRC_32CCITT.

Auch damit liefern beide Funktionen einen unterschiedlichen Wert. Ich glaube nicht das es am Polynom liegt, den beim selben Polynom (egal ob CRC_32, CRC_32CCITT oder was auch immer) müssen beide Funktionen das selbe Ergebnis liefern.

Blup 24. Jul 2009 14:31

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
Üblicherweise wird die CRC-Summe vor der Berechnung mit -1 initialisiert (alle Bits gesetzt).
Man kann aber auch mit 0 beginnen (alle Bits nicht gesetzt).

Um auf das gleiche Ergebnis zu kommen, muss das Ergebnis negiert werden.
$340BC6D9 xor $FFFFFFFF = $CBF43926
oder
$340BC6D9 xor -1 = $CBF43926

gammatester 24. Jul 2009 15:24

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
Die Erklärung für die unterschiedlichen CRC-Werte hat himitsu doch schon gegeben. Wenn in Deiner Datei die neun Asciizeichen '1'..'9' bzw #49..#57 stehen, und die CRC $CBF43926 sein soll, so muss definitiv diese CRC genommenen werden, mit folgenden Rocksoft-Parametern:

Code:
CRC32_Zip: TCRCParam = (poly  : longint($04C11DB7);
                        init  : longint($FFFFFFFF);
                        xorout : longint($FFFFFFFF);
                        check : longint($CBF43926);
                        width : 32;
                        refin : true;
                        refout : true;
                        name  : 'CRC32/Zip');
                       {alias : 'CRC-32'}
                       {alias : 'CRC-32/ADCCP'}
                       {alias : 'PKZIP'}

Und beim DEC ist das nun mal CRC_32.

Schreib mal Deinen String in eine Datei und schau nach, was als Bytes drin steht. Im übrigen ist es eh nicht gut, CRCs auf Strings loszulassen, wenn man nicht weiß, was eigentlich unter der Hand passiert. Leider verschleiern das viele Blackbox-Bibliotheken.

BlueStarHH 24. Jul 2009 15:24

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
Danke, mit der Lösung von Blup klappt es!

BlueStarHH 24. Jul 2009 15:31

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
Zitat:

Zitat von gammatester
Die Erklärung für die unterschiedlichen CRC-Werte hat himitsu doch schon gegeben. Wenn in Deiner Datei die neun Asciizeichen '1'..'9' bzw #49..#57 stehen, und die CRC $CBF43926 sein soll, so muss definitiv diese CRC genommenen werden, mit folgenden Rocksoft-Parametern:

Code:
CRC32_Zip: TCRCParam = (poly  : longint($04C11DB7);
                        init  : longint($FFFFFFFF);
                        xorout : longint($FFFFFFFF);
                        check : longint($CBF43926);
                        width : 32;
                        refin : true;
                        refout : true;
                        name  : 'CRC32/Zip');
                       {alias : 'CRC-32'}
                       {alias : 'CRC-32/ADCCP'}
                       {alias : 'PKZIP'}

Und beim DEC ist das nun mal CRC_32.

Nein, beim DEC ist $04C11DB7 die CRC_32CCITT. Hier der Code aus dem DEC:

Delphi-Quellcode:
  procedure CRCTab;
  asm
    //    Polynom  Bits InitVec   FinitVec  Inverse
    DD   $000000D1, 8, $00000000, $00000000, -1   // CRC_8  GSM/ERR
    DD   $00000233, 10, $00000000, $00000000, -1   // CRC_10 ATM/OAM Cell
    DD   $0000080F, 12, $00000000, $00000000, -1   // CRC_12
    DD   $00008005, 16, $00000000, $00000000, -1   // CRC_16 ARC,IBM
    DD   $00001021, 16, $00001D0F, $00000000, 0   // CRC_16 CCITT ITU
    DD   $00008408, 16, $00000000, $00000000, -1   // CRC_16 XModem
    DD   $00864CFB, 24, $00B704CE, $00000000, 0   // CRC_24
    DD   $9DB11213, 32, $FFFFFFFF, $FFFFFFFF, -1   // CRC_32
    DD   $04C11DB7, 32, $FFFFFFFF, $FFFFFFFF, -1   // CRC_32CCITT
    DD   $04C11DB7, 32, $FFFFFFFF, $00000000, -1   // CRC_32ZModem

negaH 25. Jul 2009 22:35

Re: CRC32 mit DEC erzeugt stimmt nicht?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
CRCCalc(CRC_32CCITT, '123456789', 9)
ergibt korrekter Weise $CBF43926.

Delphi-Quellcode:
  FS := TFileStream.Create('c:\test.txt', fmOpenRead);
  try
    WriteLn(IntToHex(CRCCalcEx(CRC_32CCITT, FS.Read), 8));
  finally
    FS.Free;
  end;
ergibt ebenfalls $CBF43926 wenn die Datei wirklich nur 123456789 enthält.

Gruß Hagen

H4ndy 21. Aug 2010 10:42

AW: CRC32 mit DEC erzeugt stimmt nicht?
 
Hallo,

Ich muss diesen Thread nochmal auspacken.
Und zwar hab ich das Problem, dass das DEC 5.1 und 5.2 mir unterschiedliche CRC32-Werte bei gleichem Code liefern.

Benutze ich die CRC_157.pas von Hagen über mir, stimmt der CRC32 wert, nehm ich die CRC.pas ausm aktuellen DEC 5.2 Part I erhalte ich einen falschen Wert. Kann mir das jemand erklären?

Ich benutze Delphi 2010 Professional.

Delphi-Quellcode:
CRCInitThreadSafe;

function CheckCRC32(const AStream: TStream; TargetCRC32: string;
  out FileCRC32: string): Boolean;
var
  NumericCRC: Cardinal;
begin
  try
    NumericCRC := CRCCalcEx(CRC_32CCITT, AStream.Read);
    FileCRC32 := IntToHex(NumericCRC, 2);
    Result := CompareText(TargetCRC32, FileCRC32) = 0;
  except
    Result := False;
  end;
end;
Wie gesagt, mit der CRC.pas vom DEC 5.1 kommt der korrekte Wert raus, beim 5.2er nicht :|
Ich benutzt CRCInitThreadSafe, da ich die Berechnung später über die OTL parallelisieren möchte.

cookie22 21. Aug 2010 11:38

AW: CRC32 mit DEC erzeugt stimmt nicht?
 
schon mal den source von version 5.1 zu 5.2 auf unterschiede geprüft?

Assertor 21. Aug 2010 12:16

AW: CRC32 mit DEC erzeugt stimmt nicht?
 
Hallo H4ndy,

bitte prüfe, ob Du die gefixte Version von 17.12.2008 hast. Diese liegt bei Luckie:
http://www.michael-puff.de/Programmierung/Delphi/DEC/

Diese und ähnliche Zeilen mußt Du (mehrfach) im Source von CRC.pas finden können:
Delphi-Quellcode:
{$IFOPT O-}{$O+}{$DEFINE NoOpt}{$ENDIF}
Bis auf diesen Fix für C++ Builder und Source Code Formatierung habe ich nichts (!) im Code von CRC.pas zwischen DEC 5.1 und DEC 5.2 geändert.

Ich habe die 5.2 selbst unter 2009 im Einsatz gehabt und nutze sie nun produktiv mit Delphi 2010. Ich kann o.g. Problem nicht nachvollziehen - die CRCs stimmen. Die Rocksoft Paramter müssen ggf. zwischen DEC 3 und DEC 5.x angepasst werden, aber das ist ja hier nicht der Fall.

Vergleichst Du vielleicht Ansi & Unicode Daten? :glaskugel: Dann muß jetzt etwas anderes rauskommen.

Gruß,
Assertor


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:08 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