String Checksummer ermitteln

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
chronical_chaos
User
Beiträge: 13
Registriert: Montag 21. März 2005, 15:50

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
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi


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

und probiers mal mit check ^= ord(ch)

Gruss
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
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')
chronical_chaos
User
Beiträge: 13
Registriert: Montag 21. März 2005, 15:50

Super, danke für die Tips! Werde ich morgen gleich mal ausprobieren.

Gruß

chronical_chaos
Antworten