WinFuture-Forum.de: Crc32 Prüfsumme In C/c++ Berechnen - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

Crc32 Prüfsumme In C/c++ Berechnen


#1 Mitglied ist offline   gorko122 

  • Gruppe: aktive Mitglieder
  • Beiträge: 85
  • Beigetreten: 12. November 04
  • Reputation: 0
  • Wohnort:Hartberg - Österreich

geschrieben 29. Oktober 2005 - 16:47

Hi!
Ich suche eine Funktion, mit welcher ich die CRC32 Prüfsumme berechnen kann.

Ich habe zwar schon diverse Algorithmen gefunden, jedoch keinen, welcher es mir ermöglicht den Pfad der Datei anzugeben und ich bekomme die CRC32 als Returnwert.

Die Funktion in Wikipedia kapiere ich nicht bzw. ich weiß nicht, wie ich es umbauen kann, damit ich eine ganze beliebig große Datei damit verwenden kann:
#include <stdio.h>
   #define CRC32POLY 0x04C11DB7 /* CRC-32 Polynom */
   
   int datastream[]={1,0,0,0,1,1,0,0};
   int databits=8;
   
   unsigned long crc32; /* Shiftregister */
   void calc_crc32(int bit)
   {	int hbit=(crc32 & 0x80000000) ? 1 : 0;
		if (hbit != bit)
				crc32=(crc32<<1) ^ CRC32POLY;
		else
				crc32=crc32<<1;
		crc32 &= 0xffffffff; /* begrenze auf 32 Bits */
   }
   int main()
   {	int i;
   
		crc32=0xffffffff; /* Startwert (111... bei CRC-32) */
		for (i=0; i<databits; ++i)  
				calc_crc32(datastream[i]);
		printf("0x%08X",crc32 ^ 0xffffffff); /* invertiere Ergebnis */
   }


Ein anderes Skript habe ich auch noch gefunden und auch getestet, jedoch gibt es mir immer eine falsche Prüfsumme aus und es ist mehr als kompliziert:
// SFV_Check.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"

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 _tmain(int argc, _TCHAR* argv[]){
  FILE *werte;
  char Infos_ohne_Mac [MANUFACTURING_INFO_SIZE];

  //### warum als "r" und nicht als "rb"?
  if ( (werte = fopen("c:\\test.txt","rb"))==NULL) //Pointer auf Datei wird in werte gespeichert
  {
	printf("error opening file");
	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
	#else
	for (int i=1; i<=116; i++) { //überlesen der ersten 116 Zeichen, dürfen nicht in Berechnung eingehen
	  getc(werte);
	} 

	(int i=0; 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

  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;
}


Kann mir bitte jemand helfen - ich blicke nicht mehr durch, wie ich es anstellen soll, die CRC32 Checksum zu berechnen...

Danke
mfg
gorko
0

Anzeige



#2 Mitglied ist offline   Rika 

  • Gruppe: aktive Mitglieder
  • Beiträge: 11.533
  • Beigetreten: 11. Juni 03
  • Reputation: 2
  • Geschlecht:Männlich

geschrieben 29. Oktober 2005 - 19:12

#define CRC32POLY 0x04C11DB7 /* CRC-32 Polynom */

vs.

#define CRC32_POLYNOMIAL 0xEDB88320

Also warum wunderst du dich?
Trivialerweise kannst du einfach das korrekte Polynom aus dem ersten Codestückchen ins das zweite übernehmen, dann wird es dort auch hinhauen.
Konnichiwa. Manga wo shitte masu ka? Iie? Gomenne, sonoyouna koto ga tabitabi arimasu. Mangaka ojousan nihongo doujinshi desu wa 'Clamp X', 'Ayashi no Ceres', 'Card Captor Sakura', 'Tsubasa', 'Chobits', 'Sakura Taisen', 'Inuyasha' wo 'Ah! Megamisama'. Hai, mangaka gozaimashita desu ni yuujin yori.
Eingefügtes Bild
Ja, mata ne!

(For sending email please use OpenPGP encryption and signing. KeyID: 0xA0E28D18)
0

#3 Mitglied ist offline   gorko122 

  • Gruppe: aktive Mitglieder
  • Beiträge: 85
  • Beigetreten: 12. November 04
  • Reputation: 0
  • Wohnort:Hartberg - Österreich

geschrieben 29. Oktober 2005 - 21:56

danke für deine antwort.

es funzt leider trotzdem nicht ^_^

für was ist dieses polynom eigentlich gut?
gibt es denn keinen ordentlichen algorithmus, um die checksumme zu berechnen?
0

#4 Mitglied ist offline   Rika 

  • Gruppe: aktive Mitglieder
  • Beiträge: 11.533
  • Beigetreten: 11. Juni 03
  • Reputation: 2
  • Geschlecht:Männlich

geschrieben 29. Oktober 2005 - 23:41

Das Polynom ist dafür gut, die komplette multiplikative Gruppe von GF(2^32) zu generieren und besteht stets aus einem Produkt von körperdisjunkten primitiven Polynomen - durch diesen Aufbau generiert man einen maximal effektiven zyklischen Blockcode (BCH-Code). Die Berechnung selbst ist, wie man sieht, trivial, es ist einfach eine Division durch das Polynom über GF(2), also ein simples Bitschieben und XOR.

Ein fast genauso effektiven, allerdings noch deutlich schnellerer und simplerer Algorithmus ist ADLER32. Diesen sollte man aber nur einsetzen, wenn man in etwa mehr als 1KB an Daten verwendet, da er sonst kläglich versagt. Adler32 arbeitet mit 16Bit-Worten und berechnet s1 als die Summe aller Worte und s2 als die Summe aller Zwischenwerte von s1, jeweils Modulo 65521 (der größten Primzahl unter 2^16). s1.s2 ist dann die Prüfsumme.

Ebenfalls interessant, allerdings sehr anfällig für sehr regelmäßige Fehler, ist der Prüfsummenalgorithmus von IP (Internet Procotol). Er arbeitet ebenfalls über 16Bit-Worten, indem er sie negiert, aufaddiert und das Ergebnis wieder negiert - geht allerdings auch mit 32Bit-Worten, ist dann aber nicht mehr so effektiv.

Oder man nimmt eine kryptographische Hashfunktion und stutzt sie auf die letzten 32 Bits.


Hast du eigentlich den unteren Code mal entsprechend so verändert, daß er nicht die ersten 116 Byte übergeht und vor allem das CRC-Register mit 0xFFFFFFFF initialisiert? Und warum sind deine C-Kenntnisse so lausig, daß du nicht mal mit ganz normalen Dateien und/oder -streams umgehen kannnst? Wenn du lustig bist, memory-mappst du sie gar einfach auf ein Array!

Dieser Beitrag wurde von Rika bearbeitet: 29. Oktober 2005 - 23:43

Konnichiwa. Manga wo shitte masu ka? Iie? Gomenne, sonoyouna koto ga tabitabi arimasu. Mangaka ojousan nihongo doujinshi desu wa 'Clamp X', 'Ayashi no Ceres', 'Card Captor Sakura', 'Tsubasa', 'Chobits', 'Sakura Taisen', 'Inuyasha' wo 'Ah! Megamisama'. Hai, mangaka gozaimashita desu ni yuujin yori.
Eingefügtes Bild
Ja, mata ne!

(For sending email please use OpenPGP encryption and signing. KeyID: 0xA0E28D18)
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0