![]() |
Probleme mit CRC CCITT Prüfsumme
Hallo,
ich möchte gerne folgenden Code von C ind Delphi übersetzen. folgender Code soll in Delphi übersetzt werden.
Code:
Da ich leider keine Ahnung von C habe, hab ich mir einen Delphi Code also Vorlage gesucht welcher mir die CRC16 Prüfsumme berechnet.
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 };
Delphi-Quellcode:
Leider kommt hier eine völlig andere Prüfsumme raus.
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; Weiß jemand wo der fehler liegt? Oder kann man diesen Delphi Code überhaupt nicht für die berechnung verwenden? MfG Willy |
AW: Probleme mit CRC CCITT Prüfsumme
Ändere mal die Deklaration deiner Funktion wie folgt:
Delphi-Quellcode:
Ich habe auch den Namen der Klasse TForm1 weggelassen, denn es handelt sich ja
// AnsiString (8 Byte pro Zeichen)
Function GenerateCRC16(const s1:AnsiString):Word; um eine ganz gewöhnliche Funktion, die unabhängig vom Formular ist. |
AW: Probleme mit CRC CCITT Prüfsumme
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:
Delphi-Quellcode:
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.
CRC16 := ((ord(s[i]) and $FF) xor ((CRC16 and $FF) shl 8)) xor Crc16Tab[CRC16 shr 8];
Edit: Ausgeschlafen sehe ich gerade, daß der C-Code auch den Initalwert -1 also in Delphi CRC16 := $FFFF; benutzt. |
AW: Probleme mit CRC CCITT Prüfsumme
|
AW: Probleme mit CRC CCITT Prüfsumme
Zitat:
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 :)] |
AW: Probleme mit CRC CCITT Prüfsumme
Zitat:
|
AW: Probleme mit CRC CCITT Prüfsumme
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:
Ergebniss: 4439
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; Variante 2:
Delphi-Quellcode:
Ergebniss: 4439
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; Variante 3:
Delphi-Quellcode:
Ergebniss: 13367
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; ich habe noch verschiedene andere Varianten versucht leider führte keine zu meinem erwünschten Ergebniss. MfG Willy |
AW: Probleme mit CRC CCITT Prüfsumme
Guten Morgen,
sollte die Abfrage der Zeichenkette (AnsiString) nicht bei 1 anfangen? Auf der Position 0 sind doch die Längenangaben abgelegt.
Delphi-Quellcode:
Grüße
For i := 1 to Length(s1) do Begin
Klaus |
AW: Probleme mit CRC CCITT Prüfsumme
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:
Sicher, dass die Beispiele Strings darstellen? :?
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; |
AW: Probleme mit CRC CCITT Prüfsumme
Zitat:
Beispiel: Prüfsumme aus: "MustermannMax01011980pid006342KaliumCalciumHbLact atGlucose" Zitat:
Wo finde bzw setzte ich hier den Start_Val aus dem C programm?
Code:
#define CRC_START_VAL ((TDS_CRC)-1)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:45 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