(gelöst) 8bit CRC CITT Checksummen Problem ...

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
Ritchie
Beiträge: 86
Registriert: 29. Januar 2007 19:41

(gelöst) 8bit CRC CITT Checksummen Problem ...

Beitrag von Ritchie »

Hallo Zusammen,

ich habe für das S.N.A.P. Protocoll von hth.com eine serielle Übertragung geschrieben.
Nur habe ich Fehler in der Checksummenberechnung.

Laut Doc. soll für den String "SNAP " die Checksumme 0x11 herauskommen.
Laut Doc. soll für den String "SNAP " die Checksumme 0xb2 herauskommen.

Meine Routine gibt aber 0xe und 0x6 raus.

Hier der Code:

Code: Alles auswählen

unsigned	char	SNAP_Serial::getCheckSum8BitCRC_CITT ( unsigned char *pointer )
	{
	unsigned	char crcPolynominal = 0x18;											// X^8+X^5+X^4+1
	unsigned	char crc = 0x0;
	int		Size;

	Size = 4;          // zu Testzwecken drin, da ich hard "SNAP" und "snap" übergebe

	for (int i = 0; i < Size ; i++ )
		{
		crc = crc ^ *( pointer + ( long ) i );
		for ( int j = 0; j < 8; j++ )
			{
			if ( crc & (unsigned	char) 0x1 )
				crc = ( crc >> 1 ) ^ crcPolynominal;
			else
				crc = ( crc >> 1 );
			}
		}

	return	(	crc );
	}
Hat jemand eine Idee wo ich ansetzen kann, da ich hier nicht sehr bewandert bin.
Und laut Wiki Seite ist dieser Code wohl richtig. Nicht der schnellste (da keine Tabelle verwendet wird), aber das wäre danach dran, wenn nötig.

Gruss R.
Zuletzt geändert von Ritchie am 27. April 2011 18:15, insgesamt 1-mal geändert.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

wird zur berechnung der checksumme von "SNAP" das Terminierungszeichen mit einbezogen ?
Ich denk scho oder ?

Size = 4;
sollte dann besser
Size = 5;
sein oder ?

und wie Du durch die Kruecke mit dem size scho merken solltes ... also sowas sollte dir schon beim programmieren weh tun ...
untypisierte Datenfelder, wo man die laenge nicht weiss, sind nix wert, mit denen kannst nix anfangen !
Deswegen ist deine funktions-signatur schon falsch und sollte dringend durch
unsigned char SNAP_Serial::getCheckSum8BitCRC_CITT ( unsigned char *pointer, size_t DataLength )
ersetzt werden !

Ciao ...
Ritchie
Beiträge: 86
Registriert: 29. Januar 2007 19:41

Beitrag von Ritchie »

Hallo,

danke für den Hinweis, ist jedoch nur mein Testcode.

Eigentlich gibt es eine Membervariable, welche die Größe
der zu berechnenden Daten enthält, da "0" in einer binären Datenübertragung auch ein mögliches Zeichen ist.

Diesen Teil hatte ich aus der Routine entfernt.
Hier wird anhand des Paket Type (Request oder Anwortpaket), die Paketgröße berechnet.

Ich habe zu Testzwecken einen festen Aufruf eingebaut, um die Checksumme zu prüfen. Da mein Programm niemals den Wert "SNAP" oder "snap" hat, von denen ich die Checksumme habe.


Ich bin mir derzeit nicht sicher und werde da aber heute abend nochmals prüfen, ob der Fehler evtl. daran liegt,
das ich hier eine invertierendes Verfahren (rechts schieben), statt (links schieben) verwende.

Gruss R.
Ritchie
Beiträge: 86
Registriert: 29. Januar 2007 19:41

Beitrag von Ritchie »

Hier die Lösung als kleines Testprogram nachdem ich nochmals nach Snap und CRC gesucht habe.

Code: Alles auswählen

/****************************************************************************/
//   includes
/****************************************************************************/

#include		<stdio.h>

unsigned char		getChecksume(unsigned char	*pointer, int	size)
{
unsigned char	 crcPolynominal = 0x18;											// X^8+X^5+X^4+1
unsigned char	crc = 0x0;
int										i;
unsigned char				bit_counter;
unsigned char				data;
unsigned char				feedback_bit;

	for (i = 0; i < size; ++i )
		{
		data = pointer[i];
		bit_counter = 8;
		do
			{
			feedback_bit = (crc ^ data) & 0x01;
			if (feedback_bit == 0x01)
				{
				crc = crc ^ crcPolynominal;
				}
			crc = (crc >> 1) & 0x7F;
			if (feedback_bit == 0x01)
				{
				crc |= 0x80;
				}
			data >>= 1;
			bit_counter--;
			}while (bit_counter > 0);
		}

	return		crc;
}

/****************************************************************************/
//									main
/****************************************************************************/

int main(int argc, char *argv[])
{

unsigned char		buffer[]="SNAP";
unsigned char		buffer1[]="snap";

	printf("Checksume for '%s'  (should be 0x11)  actual value 0x%x \n",buffer, getChecksume(buffer,sizeof(buffer)-1));
	printf("Checksume for '%s'  (should be 0x17)  actual value 0x%x \n",buffer1, getChecksume(buffer1,sizeof(buffer1)-1));

	return(0); 
};

Gruss R.
Antworten