Comment calculer le crc en 32 bits ?

Soyez le premier à donner votre avis sur cette source.

Vue 27 694 fois - Téléchargée 1 217 fois

Description

Voici une classe permettant de calculer le crc d'un buffer de données en 32 bits. Simple d'utilisation, je l'ai construite de façon que les débutants puissent l'utiliser sans difficultés. Il suffit d'initialiser l'objet grâce à la méthode 'Init()' qui remplit un tableau permettant de gagner en temps machine, elle prend en paramètre le Polynome sous forme d' ULONG. Ensuite, il faut appeler la méthode 'GetCrc32()' pour récupérer le crc en ULONG.

Source / Exemple :


#include "Crc32.h"

int main(int argc, char *argv[])
{
	// objet Crc32
	Crc32	crc32;		
	
	// variable recevant le crc
	ULONG	Crc32;		

	// buffer des données
	char	buffer[] = "AZSEDV356484JF9O5?FPP4?ZYB2YUDNFIBLHPVN";

	/* Initialisation de la table de l'objet Crc32,
	le paramètre est le polynome à utiliser :
		
		- CRC32_POLY_CCITTV41		
		- CRC32_POLY_CRC16
		- CRC32_POLY_CRC12
		- CRC32_POLY_ARPA
		- CRC32_POLY_ETHERNET
		- CRC32_POLY_WINZIP

	Retourne 'false' si le polynome est invalide */

	if (!crc32.Init( CRC32_POLY_CCITTV41 ))
	{
		printf( "crc32.Init() : Erreur !\n" );
		return 0;
	}
	
	/* calcul du crc en 32 bits, le premier paramètre est un pointeur sur les données,
	 le second est la taille des données.	
	Retourne 0 si les paramètres sont invalides */

	Crc32 = crc32.GetCrc32( buffer, 39 );

	// affichage du crc
	printf( "crc32 = %d\n", Crc32 );
	
	return 0;
}

Conclusion :


Aucuns bugs connus !!!

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
5
Non int est aloué en fonction du processeur donc 64 bits si c'est un 64 bits, 32 bits si c'est un 32 bits....
Donc il conviendrait d'écrire :
unsigned long
ou
unsigned long int
Messages postés
371
Date d'inscription
dimanche 4 janvier 2004
Statut
Membre
Dernière intervention
23 septembre 2009

En faisant de Init() le constructeur et en réalisant la vérification du polynome à la compilation, voici une simplification du code Crc32 :

/***************************/

#include<cstring>
#include<string>
#include
using namespace std;

struct Crc32
{
// Liste des polynomes autorisés :
enum Polynome
{
POLY_CCITTV41 = 0x88180000,
POLY_CRC16 = 0xC0028000,
POLY_CRC12 = 0xC0780000,
POLY_ARPA = 0xC1D79480,
POLY_ETHERNET = 0x8260EDB8,
POLY_WINZIP = 0x04C11DB7
};

// Constructeur / Selection du polynome
Crc32( Polynome const & poly )
{
for ( int i=0; i <= 0xFF; ++i )
{
crc32_table[i] = Reflect( i, 8 ) << 24;
for ( int j=0; j<8; ++j )
crc32_table[i] = (crc32_table[i] << 1) ^ (crc32_table[i] & (1<<31) ? poly : 0);
crc32_table[i] = Reflect( crc32_table[i], 32 );
}
}

// Calculateur de CRC selon le polynome choisi
unsigned int operator()( char const * const & buffer, unsigned int const & taille ) const
{
if (buffer==0 || taille ==0)
return 0;
unsigned int crc32 = 0xFFFFFFFF;
for( unsigned int i = 0; i < taille; ++i)
crc32 = ( crc32 >> 8 ) ^ crc32_table[ (crc32 & 0xFF) ^ buffer[i] ];
return crc32 ^ 0xFFFFFFFF;
}

private:

// Boite à outils
static unsigned int Reflect( unsigned int const & ref, int const & taille )
{
unsigned int value = 0;
for ( int i=0; i<taille; ++i )
value |= ( ( ref >> i ) & 0x0001 ) << ( taille - i - 1 );
return value;
}

// Table de calcul
unsigned int crc32_table[256];
};

int main()
{
string buffer ( "AZSEDV356484JF9O5?FPP4?ZYB2YUDNFIBLHPVN" );
// Création + Calcul du CRC du buffer
cout << "Crc = " << hex << uppercase << Crc32( Crc32::POLY_WINZIP )( buffer.c_str(), buffer.size() ) << endl;
// même chose au ralenti...
Crc32 crc32( Crc32::POLY_WINZIP );
unsigned int resultat_crc = crc32( buffer.c_str(), buffer.size() );
cout << "Crc = " << hex << uppercase << resultat_crc << endl;
}

/***************************/

Le code devient un peu plus C++ et un peu plus portable (GNU/Linux & Win) mais reste sans doute lié à une plateforme 32 bits (à tester avec un GCC sur une IA-64).

Cordialement,
X.
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
1
Sur les systèmes 32bits, les int et les longs, sont tous deux codés sur 32 bits. Il n'y a donc pas de différence entre ces derniers.
Messages postés
371
Date d'inscription
dimanche 4 janvier 2004
Statut
Membre
Dernière intervention
23 septembre 2009

Exact, je voulais dire "unsigned int". Le lecteur aura corrigé de lui même.
Messages postés
282
Date d'inscription
dimanche 1 avril 2001
Statut
Membre
Dernière intervention
12 février 2007

il me semble me rapeller que le ulong soit de 32 bits, qui a le courage de vérifier (il est définit dans quel .h ?)

par contre non l'int n'est pas bon il vaudrait mieux un unsigned int.

ça me parait utile comme classe, mais comment tu fait par exemple pour le crc16 sur une classe exclusive de crc32 ? :/
Afficher les 6 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.