Programmieren - alles kontrollieren 4.941 Themen, 20.715 Beiträge

c-programm- crc32 berechnung von manufacturing infos

Nobody666 / 10 Antworten / Baumansicht Nickles

Hilfe!!! Anbei hab ich ein C-Programm, welches von manufacturing daten die checksumme in crc32 berechnen soll.


1. kann mir jemand sagen was:


 *((u32 *)&Manufactureing_Info [MANUFACTURING_INFO_SIZE -4]) = chksum bedeuten soll?


2. beim ausführen kommt Fehlermeldung:


 undefined reference to `util_gen_crc'


3. wo und wie übergebe ich die daten?


 


Vielen Dank schon mal im voraus!!!!!!!


 


#include <stdio.h>
#include <math.h>
typedef unsigned long u32;
#define MANUFACTURING_INFO_SIZE 140
#define CRC32_POLYNOMIAL 0xEDB88320


char Manufactureing_Info [MANUFACTURING_INFO_SIZE] = "43";



int main ()
{
 u32 chksum;
 chksum = ~ util_gen_crc (Manufactureing_Info, MANUFACTURING_INFO_SIZE -4, 0xffffffff);
 *((u32 *)&Manufactureing_Info [MANUFACTURING_INFO_SIZE -4]) = chksum;
 printf("Die checksumme ist: %08lx",chksum);
}
u32 util_gen_crc (char *pcDatabuf, u32 ulDatalen, u32 ulCrc_in)
{
 u32 idx, bit, data, crc;
 crc = ulCrc_in;
 for (idx = 0; idx < ulDatalen; idx++)
 {
  data = *pcDatabuf++;
  for (bit = 0; bit < 8; bit++, data >>=1)
  {
   crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32_POLYNOMIAL : 0);
  }
 }
 return crc;
}

bei Antwort benachrichtigen
mr.escape Nobody666 „c-programm- crc32 berechnung von manufacturing infos“
Optionen
1. kann mir jemand sagen was:
*((u32 *)&Manufactureing_Info [MANUFACTURING_INFO_SIZE -4]) = chksum bedeuten soll?

Da wird der errechnete 32bit crc wert, d.h. 4 bytes in die letzten 4 bytes des char arrays gespeichert (C typisch brutal unleserlich formuliert, muss man sich dran gewöhnen).

2. beim ausführen kommt Fehlermeldung:
undefined reference to `util_gen_crc'

Es wird die funktion util_gen_crc aufgerufen, ohne definiert zu sein (sie wird erst weiter unten definiert). Lösung main() hinter der funktion definieren oder sie früher deklarieren (einfach "u32 util_gen_crc (char *pcDatabuf, u32 ulDatalen, u32 ulCrc_in);" vor main einfügen)

3. wo und wie übergebe ich die daten?
Welche daten ? In "Manufactureing_Info" steht die zeichenkette "43" (3 bytes) und danach 137 zufällige zeichen, von denen die letzten vier bei der crc bildung nicht beachtet sondern mit dem crc wert überschrieben werden.

mr.escape
"The man who trades freedom for security does not deserve nor will he ever receive either." - Benjamin Franklin"Wer seine Freiheit aufgibt, um Sicherheit zu erreichen, wird beides verlieren." - Georg Christoph Lichtenberg
bei Antwort benachrichtigen
Nobody666 Nachtrag zu: „c-programm- crc32 berechnung von manufacturing infos“
Optionen

@ mr.escape: DANKE!!!

Hab jetzt aber wieder ein anderes Problem.
Will die Daten, die ich in der obigen Funktion berechnen will in einer Datei. Diese is im Hex Format (140 Hex Zahlen also). Diese will ich von der Datei einlesen und berechnen. Funktioniert aber nicht so wie ich will. Funktion fgetc liest mir immer nur 1 Zeichen ein und wandelt in int um, kann ich aber so nicht brauchen, hab schon in Literatur und Netz geschaut, aber nichts für mein Problem gefunden. Muß dann verschiedene Hex Werte mit Werten aus einer anderen Datei überschreiben, deswegen hab ich mir das mit den Vektoren gedacht, einfach die Hexwerte in Vektoren speichern, mit Werten aus der anderen Datei überschreiben und dann die Berechnung durchführen. Aber wie gesagt, funktioniert nicht. Wer kann BITTE helfen!!!!!!
Anbei das was ich mir schon ausgedacht habe (nicht viel, aber ich komm einfach nicht weiter):
int main ()
{
FILE *werte;
char Infos_ohne_Mac [140];

if ( (werte = fopen("C:\\test.txt","rb"))==NULL) //Pointer auf Datei wird in werte gespeichert
{
printf("error opening file C:\\test.txt\n");
exit (1);
}
else
{
for (int i=0; !feof(werte); i++)
{
Infos_ohne_Mac [i] = fgetc(werte);
}
}
fclose(werte);


printf("Der 2. Wert ist: %i\n",Infos_ohne_Mac[1]);

bei Antwort benachrichtigen
mr.escape Nobody666 „@ mr.escape: DANKE!!! Hab jetzt aber wieder ein anderes Problem. Will die Daten,...“
Optionen
Will die Daten, die ich in der obigen Funktion berechnen will in einer Datei.
Sollte wohl "aus einer Datei" heissen.

Diese is im Hex Format (140 Hex Zahlen also).
Was heisst das denn? Ist es eine textdatei mit hex zahlen oder ist eher binär statt text gemeint? "test.txt" deutet auf textfile im hex format hin, währen "rb" in fopen() auf binär.

Funktion fgetc liest mir immer nur 1 Zeichen ein und wandelt in int um
Richtig, das ist fgetc, wie es leibt und lebt!

kann ich aber so nicht brauchen
Dann nimm doch fread:
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
also hier:
int l=fread(Infos_ohne_Mac, 1, 140, werte);
für den gesamten else zweig (d.h. inkl. der for schleife, wobei die else hier ja wegen exit() eigentlich überflüssig ist). Es muss aber sicher sein, dass genug daten gelesen werden (variable l sollte genau 140 haben, bzw. 136 wegen dem crc wert). Deine version ist aber gefährlicher, da einer der gefürchteten buffer overflow fehler sich darin versteckt (probier mal eine test.txt mit einigen megabytes aus, adios stack!).

mr.escape
"The man who trades freedom for security does not deserve nor will he ever receive either." - Benjamin Franklin"Wer seine Freiheit aufgibt, um Sicherheit zu erreichen, wird beides verlieren." - Georg Christoph Lichtenberg
bei Antwort benachrichtigen
Nobody666 mr.escape „ Sollte wohl aus einer Datei heissen. Was heisst das denn? Ist es eine textdatei...“
Optionen

Danke für die schnelle Antwort.
Die Dateien, die ich lesen muß liegen in einem .dat Format vor.
Ein Beispiel wie sie in dieser Datei liegen ist:
43 00 00 8C 00 20 61 10 ... insesamt mit der Summe am Schluß 140 Zahlenpaare. Dort muß ich dann an bestimmten Stellen Zahlen überschreiben und dann chksum ausführen.

Was für eine Version würdest du denn vorschlagen, um einen buffer overflow zu vermeiden?

int I=fread(Infos_ohne_Mac,1,140,werte);
hab ich ausprobiert, bringt mir aber immer noch den gleichen Wert, auch wenn ich für size_t count 2 eingebe!?? -Seufz-
was mach ich dann eigentlich mit dem int I? Kann ich den auch weglassen?

bei Antwort benachrichtigen
mr.escape Nobody666 „Danke für die schnelle Antwort. Die Dateien, die ich lesen muß liegen in einem...“
Optionen
Die Dateien, die ich lesen muß liegen in einem .dat Format vor.
Ist die datei 140 bytes lang oder 280 oder gar 420,421 bzw. 422?
140=140 bytes binär d.h. char.
280=140 words binär d.h. short int
420=textfile im hex format, eine zeile
421=textfile im hex format, eine zeile mit 1 byte zeilenumbruch (unix style)
422=textfile im hex format, eine zeile mit 2 byte zeilenumbruch (dos style)
Was ist in notepad zu sehen, wenn diese datei damit geöffnet wird? Datenmüll oder diese zahlenreihen?

am Schluß 140 Zahlenpaare
Ist für dich 43 ein zahlenpaar oder 43 00?

Was für eine Version würdest du denn vorschlagen, um einen buffer overflow zu vermeiden?
Abbruch nach 140 zahlen (bytes oder was auch immer, je nach dem was tatsächlich gemeint ist, momentan char, wegen dem sourcecode).

was mach ich dann eigentlich mit dem int I? Kann ich den auch weglassen?
int l bedeutet, dass eine int variable namens l eingeführt wird (l wie länge, in dieser form nur in c++, d.h. nur direkt nach einer geschweiften klammer wenn c antstelle von c++ verwendet wird), und nein sie ist nicht erforderlich (gibt lediglich an, wieviele datensätze mit der grösse "size" geladen wurden, bei size=1 also die anzahl der bytes).

mr.escape
"The man who trades freedom for security does not deserve nor will he ever receive either." - Benjamin Franklin"Wer seine Freiheit aufgibt, um Sicherheit zu erreichen, wird beides verlieren." - Georg Christoph Lichtenberg
bei Antwort benachrichtigen
Nobody666 mr.escape „ Ist die datei 140 bytes lang oder 280 oder gar 420,421 bzw. 422? 140 140 bytes...“
Optionen

also,
wenn ich es mit notepad öffne ist nur Müll zu sehen, wenn ich es mit einem Editor in Hexansicht darstellen lasse, kommen diese Zahlen heraus. Insgesamt 140 Zahlen wie z.B. 43 oder 00 oder 0f und so weiter.Er muß das aber wie du schreibst in char verarbeiten.
????

bei Antwort benachrichtigen
mr.escape Nobody666 „also, wenn ich es mit notepad öffne ist nur Müll zu sehen, wenn ich es mit...“
Optionen

Also ist es eine 140 byte binär datei, die mit 43 00 00 8C 00 20 61 10 ... anfängt. Dann ist die fread methode die passende.

#define MANUFACTURING_INFO_SIZE 140
int main (){
 u32 chksum;
 FILE *werte;
 char Infos_ohne_Mac [MANUFACTURING_INFO_SIZE];

 if ((werte = fopen("C:\\test.txt","rb"))==NULL){ //Pointer auf Datei wird in werte gespeichert
  printf("error opening file C:\\test.txt\n");
  exit (1);
 }
 fread(Infos_ohne_Mac, 1, MANUFACTURING_INFO_SIZE, werte);
 fclose(werte);
 chksum = ~ util_gen_crc (Infos_ohne_Mac, MANUFACTURING_INFO_SIZE -4, 0xffffffff);
 *((u32 *)&Infos_ohne_Mac[MANUFACTURING_INFO_SIZE -4]) = chksum;
 printf("Die checksumme ist: %08lx\n",chksum);
}

mr.escape

"The man who trades freedom for security does not deserve nor will he ever receive either." - Benjamin Franklin"Wer seine Freiheit aufgibt, um Sicherheit zu erreichen, wird beides verlieren." - Georg Christoph Lichtenberg
bei Antwort benachrichtigen
Nobody666 mr.escape „Also ist es eine 140 byte binär datei, die mit 43 00 00 8C 00 20 61 10 ......“
Optionen

Also, hab mich nochmal damit beschäftigt, hab jetzt folgende Lösung, funktioniert leider nicht:

#include

bei Antwort benachrichtigen
mr.escape Nobody666 „Also, hab mich nochmal damit beschäftigt, hab jetzt folgende Lösung,...“
Optionen
Also, hab mich nochmal damit beschäftigt, hab jetzt folgende Lösung, funktioniert leider nicht:
Meine antwort lautet so (kommentare mit //### sind von mir, bedingtes compilieren mit alternative):

#include
typedef unsigned long u32;
#define MANUFACTURING_INFO_SIZE 140 //komplettes Feld incl. chksum
#define CRC32_POLYNOMIAL 0xEDB88320
char Manufactureing_Info [MANUFACTURING_INFO_SIZE];
u32 util_gen_crc (char *pcDatabuf, u32 ulDatalen, u32 ulCrc_in);

int main (){
  FILE *werte;
  char Infos_ohne_Mac [MANUFACTURING_INFO_SIZE];

  //### warum als "r" und nicht als "rb"?
  if ( (werte = fopen("M:\\1409101.lb0","r"))==NULL) //Pointer auf Datei wird in werte gespeichert
  {
    printf("error opening file M:\\1409101.lb0\n");
    exit(0);
  } else {
#if 1
    fseek(werte, 116, SEEK_SET);//überspringen von 116 bytes
    fread(Infos_ohne_Mac, 1, MANUFACTURING_INFO_SIZE, werte);//einlesen von MANUFACTURING_INFO_SIZE bytes
    //### unten fehler, da ab index 1 gelesen wird, d.h. erstes char undefiniert und ein extra char wird überschrieben!!!
    //### in c/c++ beginnen arrays bei 0 und nicht bei 1!, also müsste es heissen:
    //### for (int i=0; i<MANUFACTURING_INFO_SIZE; i++){
    //### Infos_ohne_Mac [i] = getc(werte);
    //### }
    //### die letzten vier bytes werden dabei auch nicht gebraucht (nicht in crc und später überschrieben)
#else
    for (int i=1; i<=116; i++) { //überlesen der ersten 116 Zeichen, dürfen nicht in Berechnung eingehen
      getc(werte);
    } //verlassen for-Schleife

    for (int i=1; i<=MANUFACTURING_INFO_SIZE; i++)
    {
      Infos_ohne_Mac [i] = getc(werte); //Einlesen und speichern in Infos_ohne_Mac der relevanten Daten für Berechnung

    }
#endif

  } //verlassen if-Schleife
  fclose(werte); //Datei schließen

  //### was soll das zweite, aus der datei gelesene byte aussagen? Und warum als %c und nicht als %02X?
  printf("Der 2. Wert ist: %c\n",Infos_ohne_Mac[2]); //Darstellung der Checksumme im Ascii Test!!wird später gelöscht


  u32 chksum;
  chksum = ~ util_gen_crc (Infos_ohne_Mac, MANUFACTURING_INFO_SIZE -4, 0xffffffff); //checksumme berechnen

  /*der errechnete crc wert wird in die letzten 4 bytes des char arrays gespeichert (chksum):*/
  *((u32 *)&Infos_ohne_Mac [MANUFACTURING_INFO_SIZE -4]) = chksum;




  printf("Die checksumme ist: %08lx",chksum); //Test!!(wird später entfernt)

}

/* ***************************** ende main ******************************************************************* */


//Funktion, die CRC 32 Wert berechnet. Ist vorgegeben, darf nicht verändert werden!

u32 util_gen_crc (char *pcDatabuf, u32 ulDatalen, u32 ulCrc_in)
{
  u32 idx, bit, data, crc;
  crc = ulCrc_in;
  for (idx = 0; idx < ulDatalen; idx++)
  {
    data = *pcDatabuf++;
    for (bit = 0; bit < 8; bit++, data >>=1)
    {
      crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32_POLYNOMIAL : 0);
    }
  }
  return crc;
}

mr.escape
"The man who trades freedom for security does not deserve nor will he ever receive either." - Benjamin Franklin"Wer seine Freiheit aufgibt, um Sicherheit zu erreichen, wird beides verlieren." - Georg Christoph Lichtenberg
bei Antwort benachrichtigen
Nobody666 Nachtrag zu: „c-programm- crc32 berechnung von manufacturing infos“
Optionen

Funktioniert jetzt, mußte an meinem letzten Entwurf nur die Zeigerarithmetik ändern.
Dankeschön nochmal!!!!!!!!

bei Antwort benachrichtigen