Hallo, ich schreibe gerade an einem Sicherheitsrelevanten Programm für meine Diplomarbeit. Mein problem ist, dass ich eine Checksumme über ein Struct^2 machen möchte. Beispiel : unsigned long int Function_CRC(BAUM baumvariable); typedef struct grosser_ast { char Blatt[5]; int Blattanzahl; }grosser_ast; // 7Byte typedef struct BAUM{ grosser_ast Ast1; char Ast2[5]; int Astanzahl; }BAUM; //14Byte int Main(void){ unsigned long int crcvalue; BAUM Eiche; //14Byte strcpy(Eiche.Ast1.Blatt,"Grün"); Eiche.Ast1.Blattanzahl=2; strcopy(Eiche.Ast2,"Braun"); Eiche.Astanzahl=2; crcvalue=Function_CRC(Eiche); } das CRC wird schematisch wie folgt berechnet: unsigned long int Function_CRC(BAUM baumvariable){ for (i=0;i<14;i++){//weil baumvariable 14Byte checksum = (checksum >> 8) ^ crc_table[*(&baumvariable+i) ^ (checksum & 0xff)];} retur checksum; } hat vielleicht jemand eine Idee, wie ich das Strukt BAUM in der Function_CRC byteweise für eine CRC-Berechnung benutzen muss ? Ich habe schon etliche Pointervariantetn für *(&baumvariable+i)ausprobiert. Vielen Dank im vorraus. Gruss Max
Hallo Max! So wie ich das sehe, brauchst Du bei der Funktion "Function_CRC" einen Zeiger auf die Struktur BAUM. unsigned long int Function_CRC(BAUM *baumvariable); Danach kannst Du mit dem Pointer arbeiten. Noch einfacher wäre es, wenn Du Dir eine allgemeine Funktion erstellst, die Dir beginnend bei einem Zeiger für eine gewisse Länge ausgehend von einem CRC-Startwert die Summe erzeugt. unsigned long int Function_GenericCRC(unsigned char *uc_data, unsigned int i_length, unsigned long int ul_crc); Dann kannst Du Deine Funktion "Function_CRC" umschreiben, dass sie mit Deinen Bäumen zurechtkommt. Viel Spaß damit!
Hallo Rainer, vielen Dank für Deine schnelle Antwort. Dein Hinweis für eine universelle Funktion, die den CRC für eine variableLänge berechnet finde ich sehr gut. (Ähnliche Ideen hatte ich auch schon.) Meinst du damit, dass ich die Teile des Strukts einzeln berechnen muss ? Also in etwa so ?? unsigned long int Function_GenericCRC(unsigned char *uc_data, unsigned int i_length, unsigned long int ul_crc); chk=0; chk=CRC(Eiche.Ast1.Blatt,5,chk); chk=CRC(Eiche.Ast1.Blattanzahl,2,chk); chk=CRC(Eiche.Ast2,5,chk); chk=CRC(Eiche.Astanzahl,5,chk); .. und wenn ja, adressiere ich *uc_data wie folgt :? for (i=0;i<i_length;i++){ ....*(uc_data+i)....//soll inhalt von uc_data an position i sein } nochmals vielen Dank. Max
Du musst nicht die Teile der struct einzeln berechnen, sondern die Bytes der struct. Eine CRC wird über einen Bytestrom ermittelt. Damit hilft auch kein Zeiger auf die struct selbst, sondern nur ein Zeiger auf uint8_t (in einen solchen musst du die Adresse der struct beim Aufruf wandeln). CRC-Funktionen gibt's übrigens in der avr-libc (falls du einen AVR nimmst -- du schreibst nichts dazu). Eine CRC über eine struct ist u. U. etwas widersinnig, da du damit auch das Padding zwischen den Elementen der struct mit der CRC mit absicherst. Weiß nicht, ob das wirklich das ist, was du willst. Ist für den AVR kein Thema (der hat kein Padding), aber für andere Prozessoren schon. Normalerweise appliziert man eine CRC nur auf externe Kommunikation, nicht auf irgendwelche internen Daten -- und dort ergibt sich der Bytestrom (octet stream) dann in der Regel von selbst.
Hallo Jörg, Danke für die Antwort. der Prozessor ist ein i386 kompatibler amd Prozessor (in einem PanelPc) Der Compiler ist GCC. (2.95) Ich muss meinen Speicher während des Betriebs überwachen um EMV-Störungen und ähnliche Fehlerquellen auschliessen zu können, die theoretisch auftrete könnten. Das heisst ich muss Checksummen über den flüchtigen Speicher und noch über weitere Speicherbereiche bilden (Flashkarte....Adressleitungstest und so weiter.. viel viel überprüfen) Ich weiss auch, dass ein CRC Byteweise generiert wird. Wenn ich aber ein Strukt habe, das komplizierter ist als in meinem meinem Beispiel, welches aus sehr vielen verschiedenen Datentypen (ulint,usint,char[],*char) besteht, habe ich ein Problem mit der Adressierung der einzelnen Bytes in meinem Speicher. Das CRC über den flüchtigen Speicher ist nur während der Laufzeit nötig. Nach einem Neustart wird alles wieder neu berechnet. (Ausser auf der Flashkarte); Danke nochmal Gruss Max
das padding problem sollte sich doch mit einem einfachen #pragma pack(1) erledigen lassen oder??? zumindest hauts am arm mit dem gcc hin und der compiler vom VStudio6 tuts auch ;) auf jedenfall darf das ganze dann ca so ausschaun:
1 | //im header...
|
2 | #pragma pack(1)
|
3 | int crc_function(char *pData, int nLen); |
4 | |
5 | //in der .c
|
6 | int crc_function(char *pData, int nLen) { |
7 | int i; |
8 | for (i=0;i<nLen;i++) { |
9 | //dein crc-code
|
10 | }
|
11 | return nCRC |
12 | }
|
13 | |
14 | //irgendwo im code...
|
15 | BAUM sBaum; |
16 | int crc_value=crc_function((char *)&sBaum,sizeof(BAUM)); |
das sollte eigentlich hinhaun .. 73
Hans.... super vielen Dank ! der Cast auf den Charpointer hat mir gefehlt . Ich habe immer auf char gecastet :-) naja nochmal an alle vielen Dank für die schnelle und prompte Hilfe. Bis zum nächsten mal Max Damit würde ich den Thread schliessen.
Solange es nur darauf ankommt, den von den Daten benutzten Speicher auf Veränderungen hin zu überwachen, kann einem ja auch das Padding egal sein: man überwacht eben die Padding-Bytes mit, egal was da gerade drin steht. > Wenn ich aber ein Strukt habe, das komplizierter ist als in meinem > meinem Beispiel, welches aus sehr vielen verschiedenen Datentypen > (ulint,usint,char[],*char) besteht, habe ich ein Problem mit der > Adressierung der einzelnen Bytes in meinem Speicher. Nein, du hast das Prinzip einfach noch nicht verstanden: du willst immer noch die CRC für jedes struct tag einzeln berechnen. Das ist Quatsch. Du berechnest die CRC über den gesamten von der struct belegten Speicher, ohne Rücksicht auf die Details. Hans hat das ja schon angedeutet, das mit dem #pragma pack() kannst du weglassen. (Der GCC nimmt sowieso keine Pragmas, bei ihm wäre das ein __attribute__((packed)).)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.