Seite 1 von 1

String Checksummer ermitteln

Verfasst: Samstag 18. Juni 2005, 15:39
von chronical_chaos
Hallo NG,

ich habe ein Python Programm geschrieben, mit welchem ich Daten über die serielle Schnittstelle an einen Controller senden und vom Controller empfangen kann.

Die Daten werden bisher ohne Checksumme übertragen. Um zumindest einigermaßen sicherzugehen, daß die Daten die versendet werden auch die sind die ich empfange möchte ich mit den sogenannten Längsparitäten arbeiten.

Dazu wird zuerst ein willkürlicher Startwert festgelegt
Danach wird der String durchlaufen, der Startwert um 1Bit nach links geshiftet und mit diesem Wert XOR verknüpft.
Der auf diese Art ermittelte Wert zusätzlich an den Empfänger geschickt.

Der Empfänger durchläuft ebenfalls den String und führt o.g. Operationen aus.
Am Ende vergleicht er den Wert den er selbst ermittelt hat, mit dem den er erhalten hat. Stimmen diese überein, war die Übertragung erfolgreich.

Damit klarer wird was ich meine hier ein kleines C-Progrämmsche:

Code: Alles auswählen

// Einfache Checksumme.cpp :

#include "stdafx.h"
#include <stdio.h>
#include <string.h>

void main(void)
{
	char string[10]="abc";
	char ch;
	int i_len;
	int i;
	int i_StartVal= 0x8F;
	int check;
	int check1Val;
	//int check2Val;

	//Sender
        i_len= strlen(string);
	
	check= i_StartVal;
	for(i = 0; i < i_len; i++)
	{
		ch= string[i];
		check <<= 1;
		check ^= ch;
		check1Val= check;
		//printf("check= %X\n", check);
	}
	printf("check1Val= %X\n", check1Val);
	
	//Empfänger 
        i_len= strlen(string);

        check= i_StartVal;
	for(i = 0; i < i_len; i++)
	{
		ch= string[i];
		check <<= 1;
		check ^= ch;
		//check2Val= check;
		//printf("check= %X\n", check);
	}
	printf("check2Val= %X\n", check);
	
	
	if(check == check1Val)
	{
		printf("Success, check= %d\n", check);
	}
	else
	{
		printf("Failure, check= %d\n", check);
	}
}
Die Python Funktion die die Daten versendet sieht folgendermaßen aus.

Code: Alles auswählen

def send_file(self, filename ):
        try:
            try:
                file = open( filename ,"rb" )
            except:
                print "Cant open file" , filename
                import traceback
                traceback.print_exc()
            
            data = file.read()  # whole content of file as string

            #Cecksumme berechnen
	    StartVal= 0x8F
	    check= StartVal
	    for i in xrange(0, len(data)):
		ch= data[i]
		check <<= 1
		check^= ch
		CheckSum= check
	    
	    # send each byte with one write(); write() can send multiple bytes, too
            for char in data:
                #print repr(char)
                status = self.__prt.write(char)
                #print status
            self.__prt.write( '\x17')	#ETB End of Transmission Block senden
            #print  '\x1B'
            #print repr( '\x1B')
	    self.__prt.write(CheckSum) #Checksumme senden
	    print "Checksumme=", CheckSum
	    self.__prt.write( '\x1B')	#ESC senden -> Übertragung abgeschlossen
	except:
                print "Unknown error in send_file"
                import traceback
                traceback.print_exc()
Ich habe versucht oben beschriebenes Verfahren in die Senderoutine zu implementieren, allerdings erhalte beim ausführen folgende Fehlermeldung:


check^= ch
TypeError: unsupported operand type(s) for ^=: 'int' and 'str'


Offensichtlich verhält sich Python was die XOR Verknüpfung zweier unterschiedlicher Datentypen anbelangt anders als C.

Kann mir vielleicht jemand von Euch sagen, wie ich die Sache richtig angehen, bzw. ich dieses Problem löse.

Voraussetzung ist natürlich, daß sowohl der C als auch der Python Algo nach Durchlauf des gleichen Strings auf den selben Wert kommen.

Wäre super, wenn mir diesbezüglich jemand weiterhelfen kannt.

Gruß

chronical_chaos

Verfasst: Samstag 18. Juni 2005, 16:20
von rayo
Hi


Die einrückung in deinem quelltext stimmt nicht, kannst du das mal korrigieren?

und probiers mal mit check ^= ord(ch)

Gruss

Re: String Checksummer ermitteln

Verfasst: Samstag 18. Juni 2005, 16:29
von Leonidas
chronical_chaos hat geschrieben:Ich habe versucht oben beschriebenes Verfahren in die Senderoutine zu implementieren, allerdings erhalte beim ausführen folgende Fehlermeldung:

check^= ch
TypeError: unsupported operand type(s) for ^=: 'int' and 'str'

Offensichtlich verhält sich Python was die XOR Verknüpfung zweier unterschiedlicher Datentypen anbelangt anders als C.
ch darf halt kein String sein.

Verfasst: Samstag 18. Juni 2005, 20:45
von BlackJack
Die Prüfsumme kann man auch während des Versendens der einzelnen Zeichen berechnen. Neben dem Umwandeln in eine Zahl musst Du noch darauf achten, das die Zahl im Bereich zwischen 0 und 255 bleibt und das Du sie zum versenden wieder in ein einzelnes Zeichen, also Byte umwandelst.

Code: Alles auswählen

checksum_seed = 0x8f

checksum = checksum_seed
for char in data:
    checksum <<= 1
    checksum ^= ord(char)
    checksum &= 0xff
    # oder in einer Zeile:
    # checksum = ((checksum << 1) ^ ord(char)) & 0xff
    status = self.__prt.write(char)
    self.__prt.write( '\x17')
    self.__prt.write(chr(checksum))
    self.__prt.write( '\x1B')

Verfasst: Montag 20. Juni 2005, 20:38
von chronical_chaos
Super, danke für die Tips! Werde ich morgen gleich mal ausprobieren.

Gruß

chronical_chaos