CRC32 einer Structur - Code Beispiel

bennot

Mitglied
Hallo,

Ich will von einer Struture die Prüfsumme bilden.
Dazu habe ich folgenden Code implentiert:

Code:
unsigned long reg32 = 0xffffffff;     // Schieberegister
 
unsigned long crc32_bytecalc(unsigned char byte)
{
  int i;
  unsigned long polynom = 0xEDB88320;    // Generatorpolynom

    for (i=0; i<8; ++i)
  {
        if ((reg32&1) != (byte&1))
             reg32 = (reg32>>1)^polynom; 
        else 
             reg32 >>= 1;
    byte >>= 1;
  }
  return reg32 ^ 0xffffffff;       // inverses Ergebnis, MSB zuerst
}

unsigned long crc32_messagecalc(unsigned char *data, int len)
{
  int i;

  for(i=0; i<len; i++) 
  {
    crc32_bytecalc(data[i]);    // Berechne fuer jeweils 8 Bit der Nachricht
  }
  return reg32 ^ 0xffffffff;
}

int _tmain(int argc, _TCHAR* argv[])
{  
unsigned int	x = sizeof(MEINE_STRUCT);
  unsigned char data1[] = {x};
  unsigned long crc32;

  reg32 = 0xffffffff;          // Initialisiere Shift-Register mit Startwert
  crc32 = crc32_messagecalc(data1,9);
  printf("1: CRC32 = %lx\n",crc32);
  return 0;

}

Ich bilde von der sizeof() MEINER_STRUCT die Prüfsumme

unsigned int x = sizeof(MEINE_STRUCT);

Bin selbst der Meinung das das so nicht funktionieren kann, oder?


Richtig wäre es über jedes Byte der Structur die Prüfsumme zu bilden?

Lese mich gerade erst in das Thema ein und bin überfragt. Kann bitte jemand mal den Ablauf beschreiben wie ich das löse?
Danke

edit:
Am Ende soll mittels CRC32 geprüft werden, ob die Strucur A mit einer anderen aus dem selben Programm erstellten Structur B übereinstimmt.
 
Zuletzt bearbeitet:
Hi

die Prüfsumme der Länge ist natürlich sinnlos,
die wird immer gleich sein (da die Struktur unabhängig vom Inhalt immer gleich viel Byte braucht)
Die Prüfsumme für eine Variable v der Struktur s wäre so ein Aufruf:
C++:
crc32_messagecalc((unsigned char *)(&v), sizeof(s));
(mit dem ganzen Rest dazu natürlich).

edit: Wenn man beide Daten sowieso hat gehts schneller und einfacher mit memcmp,
ganz ohne Prüfsumme.
 
Code:
unsigned int y = MEINESTRUKT.WERT[0];
unsigned char data1[] = {y};
unsigned long crc32;

  // zähle länge auf array aus struct
   int a,anz_stellen=0;
   for(a=1;a<y;a*=10)                               // zähle für jede stelle
    { 
        anz_stellen++;                                         // stellen des wertes in struct
    } 


  reg32 = 0xffffffff;          // Initialisiere Shift-Register mit Startwert
  crc32 = crc32_messagecalc(data1,anz_stellen); // checksum von struct value und anzahl zeichen der value
  printf("1: CRC32 = %lx\n",crc32);
  return 0;
}

@ sheel danke für deine Antwort. Habe mich dennoch für CRC entschieden

Code funktioniert (siehe oben)


Hat noch Jemand einen Tipp, wie ich

a) die Member einer Struktur auslese? (stammen aus einer externen Datei und können beliebig sein, Name der Struktur ist fix)

b) die Werte der Member durch laufen kann (dazu muss ich erst ein mal die Member raus bekommen)


Google liefert leider nichts wirkliches..
 
@ sheel danke für deine Antwort. Habe mich dennoch für CRC entschieden
Dir ist aber bewußt, dass es bei CRC eine hohe Wahrscheinlichkeit von Kollisionen gibt? Eigentlich müßtest du trotzdem mit memcmp prüfen, ob die Strukturen gleich sind wenn die CRCs gleich waren um das auszuschliessen.
Code funktioniert (siehe oben)
Das bezweifle ich. Du bildest hier anscheinend nur vom dem ersten Wert, den du auf einen unsigned char abbildest den CRC... Wieso zählst du da die Dezimalstellen? :suspekt:
Hat noch Jemand einen Tipp, wie ich

a) die Member einer Struktur auslese? (stammen aus einer externen Datei und können beliebig sein, Name der Struktur ist fix)
Zu welchem Zeitpunkt denn? Dynamisch zur Laufzeit? Oder beim Kompilieren?
 
1. Nein das ist mir nicht bewusst. Bin absolut kein C-Experte. Danke für den Hinweiß.

2. Zählen tue ich, weil im Originalcode

crc32 = crc32_messagecalc(data1,9);

== wert von data1 / geteilt durch Anzahlstellen. Die Anzahl der Stellen sind bei mir nicht fix. Deswegen Zähle ich sie

3. Struktur stammt aus einer Externen Datei. Daran ändert sich nichts beim Kompilieren. Also richtig zur Laufzeit ?

---------------------

Glaub so langsam sind die ersten Versuche nicht zu gebrauchen. Dank meines Unwissens in C weiß ich aber auch nicht so recht wo ich ansetzen muss

Neue eindeutige Aufgabenstellung:
- Prüfsumme der Länge einer Struktur bestimmen


Code:
unsigned int size = sizeof(MEINESTRUCT);

Dann rechne ich aus der Anzahl der Bytes (sizeof) die CRC


Das klingt doch recht simpel :) Aber ob es stimmt..

Mir wurde folgende CRC Routine empfohlen:
http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/crc32.c
 
1. Nein das ist mir nicht bewusst. Bin absolut kein C-Experte. Danke für den Hinweiß.
Das hat mit C nichts zu tun. Das liegt einzig am CRC. Dieser bildet beliebige Daten auf einen 32Bit Wert ab -- das das nicht eindeutig sein kann ist logisch.
2. Zählen tue ich, weil im Originalcode

crc32 = crc32_messagecalc(data1,9);

== wert von data1 / geteilt durch Anzahlstellen. Die Anzahl der Stellen sind bei mir nicht fix. Deswegen Zähle ich sie
Ich kann mir überhaupt nicht vorstellen wozu das gut sein soll. Jedenfalls bildest du dort nur von einem "unsigned char" den CRC, und nicht von deiner gesamten Struktur.
3. Struktur stammt aus einer Externen Datei. Daran ändert sich nichts beim Kompilieren. Also richtig zur Laufzeit ?
Vielleicht solltest du erstmal erklären wozu das gut sein soll.

Und in welcher Form liest du die Struktur aus der Datei aus? Doch wohl einfach binär als Array in den Speicher (wenn du die Struktur nicht kennst). Dann kannst du doch auch einfach memcmp drauf aufrufen und bist fertig...?

Es wäre auch ganz nett eine Beispielstruktur mal zu sehen, damit man hier nicht immer Rumraten muss.

---------------------

Neue eindeutige Aufgabenstellung:
- Prüfsumme der Länge einer Struktur bestimmen
Aha, dann passt dein Code aus Beitrag 1 schon fast.
Code:
unsigned int size = sizeof(MEINESTRUCT);

Dann rechne ich aus der Anzahl der Bytes (sizeof) die CRC
Genau.
 
Zuletzt bearbeitet:
Zurück