AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Probleme mit CRC CCITT Prüfsumme

Ein Thema von willyxv · begonnen am 8. Jun 2011 · letzter Beitrag vom 9. Jun 2011
Antwort Antwort
Seite 1 von 2  1 2      
willyxv

Registriert seit: 25. Okt 2010
29 Beiträge
 
Delphi XE Enterprise
 
#1

Probleme mit CRC CCITT Prüfsumme

  Alt 8. Jun 2011, 21:03
Hallo,

ich möchte gerne folgenden Code von C ind Delphi übersetzen.

folgender Code soll in Delphi übersetzt werden.
Code:
typedef unsigned short TDS_CRC;
#define CRC_START_VAL ((TDS_CRC)-1)
#define CRC_TAB_SIZE  256 

TDS_CRC tGetBlockCrc(UINT8 * pBlockStart, UINT32 u32Length)
{
TDS_CRC tds_crc=CRC_START_VAL;
        while (0 < u32Length--)
        {
                tds_crc = dscrcbyte(tds_crc, *pBlockStart++);
        }
        return tds_crc;
}

#define dscrcbyte( Old_crc_us, New_dat_uc) \
                        (\
                          (\
                                        (TDS_CRC) (New_dat_uc ^ ((Old_crc_us & 0x00ff) << 8))\
                                )\
                                ^ \
                                (\
                                        (TDS_CRC) (Crc_tab[(Old_crc_us >> 8)])\
                                )\
                        )

const TDS_CRC Crc_tab[CRC_TAB_SIZE] ={//the table containing (0x1021) Generatorpolynom
        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129,
        0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252,
        0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c,
        0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
        0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672,
        0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738,
        0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861,
        0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
        0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
        0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5,
        0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b,
        0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
        0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9,
        0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3,
        0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c,
        0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
        0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3,
        0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
        0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676,
        0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
        0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c,
        0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16,
        0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b,
        0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
        0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36,
        0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
Da ich leider keine Ahnung von C habe, hab ich mir einen Delphi Code also Vorlage gesucht welcher mir die CRC16 Prüfsumme berechnet.

Delphi-Quellcode:
Const Crc16Tab : Array[0..255] of Word = (
$0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7,
$8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef,
$1231, $0210, $3273, $2252, $52b5, $4294, $72f7, $62d6,
$9339, $8318, $b37b, $a35a, $d3bd, $c39c, $f3ff, $e3de,
$2462, $3443, $0420, $1401, $64e6, $74c7, $44a4, $5485,
$a56a, $b54b, $8528, $9509, $e5ee, $f5cf, $c5ac, $d58d,
$3653, $2672, $1611, $0630, $76d7, $66f6, $5695, $46b4,
$b75b, $a77a, $9719, $8738, $f7df, $e7fe, $d79d, $c7bc,
$48c4, $58e5, $6886, $78a7, $0840, $1861, $2802, $3823,
$c9cc, $d9ed, $e98e, $f9af, $8948, $9969, $a90a, $b92b,
$5af5, $4ad4, $7ab7, $6a96, $1a71, $0a50, $3a33, $2a12,
$dbfd, $cbdc, $fbbf, $eb9e, $9b79, $8b58, $bb3b, $ab1a,
$6ca6, $7c87, $4ce4, $5cc5, $2c22, $3c03, $0c60, $1c41,
$edae, $fd8f, $cdec, $ddcd, $ad2a, $bd0b, $8d68, $9d49,
$7e97, $6eb6, $5ed5, $4ef4, $3e13, $2e32, $1e51, $0e70,
$ff9f, $efbe, $dfdd, $cffc, $bf1b, $af3a, $9f59, $8f78,
$9188, $81a9, $b1ca, $a1eb, $d10c, $c12d, $f14e, $e16f,
$1080, $00a1, $30c2, $20e3, $5004, $4025, $7046, $6067,
$83b9, $9398, $a3fb, $b3da, $c33d, $d31c, $e37f, $f35e,
$02b1, $1290, $22f3, $32d2, $4235, $5214, $6277, $7256,
$b5ea, $a5cb, $95a8, $8589, $f56e, $e54f, $d52c, $c50d,
$34e2, $24c3, $14a0, $0481, $7466, $6447, $5424, $4405,
$a7db, $b7fa, $8799, $97b8, $e75f, $f77e, $c71d, $d73c,
$26d3, $36f2, $0691, $16b0, $6657, $7676, $4615, $5634,
$d94c, $c96d, $f90e, $e92f, $99c8, $89e9, $b98a, $a9ab,
$5844, $4865, $7806, $6827, $18c0, $08e1, $3882, $28a3,
$cb7d, $db5c, $eb3f, $fb1e, $8bf9, $9bd8, $abbb, $bb9a,
$4a75, $5a54, $6a37, $7a16, $0af1, $1ad0, $2ab3, $3a92,
$fd2e, $ed0f, $dd6c, $cd4d, $bdaa, $ad8b, $9de8, $8dc9,
$7c26, $6c07, $5c64, $4c45, $3ca2, $2c83, $1ce0, $0cc1,
$ef1f, $ff3e, $cf5d, $df7c, $af9b, $bfba, $8fd9, $9ff8,
$6e17, $7e36, $4e55, $5e74, $2e93, $3eb2, $0ed1, $1ef0
);

Function TForm3.GenerateCRC16(Var s1:String):Word;
Var crc16:Word; i:Integer;
Begin
  crc16 := 0;
  For i := 1 to Length(s1) do Begin
    Crc16 := Crc16Tab[((Crc16 shr 8 ) xor Ord(s1[i])) and $ff] xor ((Crc16 shl 8) and $FFFF);
  End;
  Result := crc16;
End;

Procedure TForm3.Button1Click(Sender: TObject);
Var crc16:Word; s1:String;
Begin
  s1 := '274545957911547';

    crc16 := GenerateCRC16(s1);
    Memo1.Lines.Add(IntTostr(crc16));

End;
Leider kommt hier eine völlig andere Prüfsumme raus.

Weiß jemand wo der fehler liegt? Oder kann man diesen Delphi Code überhaupt nicht für die berechnung verwenden?

MfG Willy

Geändert von willyxv ( 8. Jun 2011 um 21:08 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: Probleme mit CRC CCITT Prüfsumme

  Alt 8. Jun 2011, 21:30
Ändere mal die Deklaration deiner Funktion wie folgt:
Delphi-Quellcode:
// AnsiString (8 Byte pro Zeichen)
Function GenerateCRC16(const s1:AnsiString):Word;
Ich habe auch den Namen der Klasse TForm1 weggelassen, denn es handelt sich ja
um eine ganz gewöhnliche Funktion, die unabhängig vom Formular ist.
  Mit Zitat antworten Zitat
gammatester

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

AW: Probleme mit CRC CCITT Prüfsumme

  Alt 9. Jun 2011, 00:04
Neben der Ansistring-Problematik: Für (New_dat_uc ^ ((Old_crc_us & 0x00ff) << 8)) ^ Crc_tab[(Old_crc_us >> 8)] gilt:

Old_crc_us entspricht CRC16, New_dat_uc entspricht (ord(s[i]) and $FF), also muß der Delphicode doch wohl eher wie folgt aussehen:

CRC16 := ((ord(s[i]) and $FF) xor ((CRC16 and $FF) shl 8)) xor Crc16Tab[CRC16 shr 8]; Wie man leicht sieht, ist der Tabellenindex nur CRC16 shr 8 (ein and $FF kann man sich sparen, da CRC16 ein word ist). Außerdem ist es immer hilfreich, wenn man einige komplette Testbeispiele angibt.

Edit: Ausgeschlafen sehe ich gerade, daß der C-Code auch den Initalwert -1 also in Delphi CRC16 := $FFFF; benutzt.

Geändert von gammatester ( 9. Jun 2011 um 08:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Probleme mit CRC CCITT Prüfsumme

  Alt 9. Jun 2011, 08:56
  1. Wieso muss man ausgerechnet genau diese C-Implementation übersetzen? Es gibt doch schon hunderte CRC-Funktionen die bereits in Delphi vorliegen. Da kann man sich den Stress sparen.
  2. Wieso wird ein Byte-Pointer zu einem String übersetzt?
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.
  Mit Zitat antworten Zitat
gammatester

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

AW: Probleme mit CRC CCITT Prüfsumme

  Alt 9. Jun 2011, 09:09
  1. Wieso muss man ausgerechnet genau diese C-Implementation übersetzen? Es gibt doch schon hunderte CRC-Funktionen die bereits in Delphi vorliegen. Da kann man sich den Stress sparen.
  2. Wieso wird ein Byte-Pointer zu einem String übersetzt?
Die Antwort auf die erste Frage ist doch ganz einfach: Der C-Code benutzt einen speziellen Algorithmus, der mit Pascal reproduziert werden soll. Da kann man doch nicht einfach einen beliebigen anderen nehmen.

Eine Antwort auch die zweite Frage suche ich auch schon seit Jahren, ich benutze immer array of byte oder einfach pByte etc. CRC oder Hash auf Delphi-Strings anzuwenden ist wahrscheinlich nur psychologisch zu erklären [Fast alles wird mit Strings gemacht; Strings werden neuerdings auch inkrementiert, und wenn man endlich 64-Bit-Stringlängen hat, kann man große Teile des Internets in einen String laden und durchsuchen ]
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#6

AW: Probleme mit CRC CCITT Prüfsumme

  Alt 9. Jun 2011, 09:27
Der C-Code benutzt einen speziellen Algorithmus [...]
Stimmt - gerade gesehen. Dann ist das aber auch kein echtes CRC. Naja, okay.
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.
  Mit Zitat antworten Zitat
willyxv

Registriert seit: 25. Okt 2010
29 Beiträge
 
Delphi XE Enterprise
 
#7

AW: Probleme mit CRC CCITT Prüfsumme

  Alt 9. Jun 2011, 10:23
Danke für die schnellen Antworten, aber erst mal zum Hintergrund.

Die Prüfsumme wird für die Ansteuerung eines Analysegeräts benötigt. Bis dato wurde dies von einer alten Software zuverlässig erledigt doch leider wurde nun eine Firmwareupdate durchgeführt und das alte Programm ist nun nicht mehr in der Lage sich mit dem Gerät zu Verbinden.
Um nun wieder die Ansteuerung zu ermöglichen, möchte ich ein neues Programm schreiben und da ich C nicht behersche, tue ich dies mit Delphi. Es klappt auch alles so weit so gut bis auf die Prüfsumme, das Gerät schickt mir als Antwort "ungültige Prüfsumme".

Die Berechnung der Prüfsumme habe ich so mit dem Beispiel aus der Anleitung entnommen. Leider sind hier nur zwei Zahlenbeispiele sowie der C Code (siehe oben) aufgeführt.
Beispiel 1: Wert: "274545957911547" Prüfsumme: "11547"
Beispiel 2: Wert: "385183474" Prüfsumme: "45942"

Ich habe nun verschiedene Variatnten Versucht mit dem Wert "274545957911547":

Variante 1:
Delphi-Quellcode:
Function TForm3.GenerateCRC16(Var s1:AnsiString):Word;
Var crc16:Word; i:Integer;
Begin
  crc16 := $FFFF;
  For i := 0 to Length(s1) do Begin
    CRC16 := (((Ord(s1[i])) xor ((Crc16 and $00FF) shl 8))) xor Crc16Tab[Crc16 shr 8];
  End;
  Result := crc16;
End;
Ergebniss: 4439


Variante 2:
Delphi-Quellcode:
Function TForm3.GenerateCRC16(Var s1:AnsiString):Word;
Var crc16:Word; i:Integer;
Begin
  crc16 := $FFFF;
  For i := 0 to Length(s1) do Begin
    CRC16 := (((Ord(s1[i]) and $00FF) xor ((Crc16 and $00FF) shl 8))) xor Crc16Tab[Crc16 shr 8];
  End;
  Result := crc16;
End;
Ergebniss: 4439

Variante 3:
Delphi-Quellcode:
Function TForm3.GenerateCRC16(Var s1:AnsiString):Word;
Var crc16:Word; i:Integer;
Begin
  crc16 := $FFFF;
  For i := 0 to Length(s1) do Begin
    CRC16 := (((Ord(s1[i])) xor ((Crc16) shl 8))) xor Crc16Tab[Crc16 and $FF shr 8];
  End;
  Result := crc16;
End;
Ergebniss: 13367


ich habe noch verschiedene andere Varianten versucht leider führte keine zu meinem erwünschten Ergebniss.

MfG Willy
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.768 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Probleme mit CRC CCITT Prüfsumme

  Alt 9. Jun 2011, 10:34
Guten Morgen,

sollte die Abfrage der Zeichenkette (AnsiString) nicht bei 1 anfangen?
Auf der Position 0 sind doch die Längenangaben abgelegt.

For i := 1 to Length(s1) do Begin Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#9

AW: Probleme mit CRC CCITT Prüfsumme

  Alt 9. Jun 2011, 10:48
Noch mal als "einfach lesbare" Version (wobei CRC16_TABLE halt die bekannte Tabelle darstellt). So entspricht es meiner Meinung nach dem C-Code. Funktioniert aber trotzdem nicht, wenn man die Beispiele berechnet.
Delphi-Quellcode:
function GenerateCRC16(const AValue: AnsiString): Word;
var
  LChar: AnsiChar;
begin
  Result := High(Result);
  For LChar in AValue do
    Result := Ord(LChar) xor (Result shl 8) xor CRC16_TABLE[Result shr 8];
end;
Sicher, dass die Beispiele Strings darstellen?
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.
  Mit Zitat antworten Zitat
willyxv

Registriert seit: 25. Okt 2010
29 Beiträge
 
Delphi XE Enterprise
 
#10

AW: Probleme mit CRC CCITT Prüfsumme

  Alt 9. Jun 2011, 11:08
Sicher, dass die Beispiele Strings darstellen?
Denke schon, im Programm wird die Prüfsumme auch aus dem Namen der zu bestimmenden Werte gebildet.

Beispiel: Prüfsumme aus: "MustermannMax01011980pid006342KaliumCalciumHbLact atGlucose"


Delphi-Quellcode:
function GenerateCRC16(const AValue: AnsiString): Word;
var
  LChar: AnsiChar;
begin
  Result := High(Result);
  For LChar in AValue do
    Result := Ord(LChar) xor (Result shl 8) xor CRC16_TABLE[Result shr 8];
end;


Wo finde bzw setzte ich hier den Start_Val aus dem C programm?
Code:
#define CRC_START_VAL ((TDS_CRC)-1)
  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 14:01 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