Crc32 compatible winrar et winzip ( basé sur le code c++ de capa6t )


Description

Voici une classe qui vous permet de générer le CRC32 d'un fichier.
Je me suis basé sur la source C++ de Capa6T (http://www.cppfrance.com/code.aspx?ID=24351)
qui marche à merveille.
La conversion en C# n'a pas été très simple mais c'était un bon challenge.
J'ai aussi essayé de le rendre un peu plus rapide en lisant des block de 4ko au lieu de lire
byte par byte , ce qui peu rendre le calcul de fichiers volumineux tres long.
Je vous epargne les détails (si vous en voulez , les sources sont pleins de commentaires ^^ )

Vous pouvez vous servir directement de cette classe en l appelant ainsi :
uint crc = CRC32.GetCrc32( "nom_de_fichier.ext" , false , null ) ; // sans bar de progression.
uint crc = CRC32.GetCrc32( "nom_de_fichier.ext" , true , System.Windows.forms.ProgressBar ) //avec bar de progression

/* NOTE : Utilisez cette fonction dans un thread , ca évitera de "figer" votre appli */

Dans le zip j'ai inclus ma source C# et celle que j ai ecris en C++ (avec la classe de l'auteur original dedans).

Source / Exemple :


using System;
using System.Windows.Forms;
using System.IO;

		//************************************************************
		//			CALCUL CRC32 EN C#	
		//		           27 janvier 2005 par lunatik
		//		 Base sur le code C++ de Capa6T
		//	      http://www.cppfrance.com/code.aspx?ID=24351
		//	(et mon site -> http://www.kawaiistudio.no-ip.com/lunatikv6 ^^ )
		//	Merci à Xya et cbeyls de csharpfr.com pour leurs conseils !
		//************************************************************

namespace CRC32
{
	public class CRC32
	{
		/// <summary>
		/// Calculer un CRC32 ( Cyclic Redundancy Check ) d'un fichier.
		/// </summary>
		/// <param name="filePath">Chemin du fichier.</param>
		/// <param name="enableProgress">Si enableProgress est vrai , la progression du calcul sera affiche
		/// dans le System.Windows.Forms.ProgressBar que vous aurez definit en 3eme argument de cette fonction</param>
		/// <param name="pBar">Le ProgressBar ou sera affiche la progression ( si enableProgress est "faux" mettez "null" ).</param>
		/// <returns>Le CRC sous forme de uint ( 32bit unsigned ) , utilisez crc32.ToString("X"); pour l'affichage
		/// hexadecimal.</returns>
		public static uint GetCrc32( string filePath , bool enableProgress ,ProgressBar pBar )
		{
			int myTimer = Environment.TickCount;
			//on initialise un filestream.
			FileStream myStream = new FileStream( filePath , FileMode.Open , FileAccess.Read );
			//On stock la taille du fichier.
			long fileSize = myStream.Length;
			if( enableProgress ) pBar.Maximum = ( int )fileSize + 2 ;

			//quelques variables...
			uint[]	LookUpTable	= new long[ 256 ];
			uint 	poly		= 0xEDB88320;
			uint 	crc32		= 0;
			//   *NOTE* , je n'utilise pas le meme polynome que celui utilise dans la source C++ dont je me suis inspire
			//   ni le meme algorithme pour generer la Table , mais au final la table est strictement la meme. ^^

			uint val;
			//Generation de la Table
			for( int i = 0 ; i <= 0xFF ; ++i)
			{
				val = i;
				for( int j = 8 ; j > 0 ; --j )
				{
					//Capa6T , dans sa source faisait une comparaison booleene 
					// en calculant    val & 1 qui donne 1 ou 0  donc true ou false en C++
					//or en C# on ne peut plus utiliser 1 et 0 (ni -1 d ailleurs) pour faire une comparaison booleene
					// ** c etait juste une petite note ^^ **
					if( ( val & 1 ) == 1 )
					{
						val = ( val >> 1 ) ^ poly ; 	// <-- la j'ai un peu compresse l equation, mais ca passe hehe : )
					}
					else
						val >>= 1 ;						
				}
				LookUpTable[ i ] = val; // on stock le resultat dans notre table. 
			}

			/* si vous voulez voir a quoi ressemble la table.
			 *

  • string table = "";
  • for( int z = 0 ; z <= 0xFF / 3 ; )
  • {
  • table += "0x" + LookUpTable[ z ].ToString("X");
  • table += " , 0x" + LookUpTable[ z+1 ].ToString("X");
  • table += " , 0x" + LookUpTable[ z+2 ].ToString("X") + "\n";
  • z+=3;
  • }
  • MessageBox.Show( table );
  • /
//on va lire le fichier par block de 4096 byte (4k) pour eviter un surchargement de memoire. //NOTE : cette partie du code à été modifiée, utilisons la méthode de cbeyls //, plus simple , pratique et econome ( mieux quoi ... ^^" ) byte[] byteArray = new byte[ 4096 ]; int readBytes; crc32 = 0xFFFFFFFF; while( ( readBytes = myStream.Read( byteArray , 0 , 4096 ) ) != 0 ) { for( int y = 0 ; y < readBytes ; ++y) { //maintenant voici le tit bout de code qui vient de la source de Capa6T //qui genere un CRC32 avec notre Table generee precedement. crc32 = ( crc32 >> 8 ) ^ LookUpTable[ ( crc32 & 0xFF ) ^ byteArray[ y ] ]; } if( enableProgress ) pBar.Value = offset ; } //fermeture du stream myStream.Close(); int mySecondTimer = Environment.TickCount; //ca c'est si vous voulez connaitre le temps int ms = mySecondTimer - myTimer; //de calcul exact en m.seconds. //MessageBox.Show( "Le CRC32 a ete calcule en "+ ms.ToString() + " Millisecondes.","Infos"); return crc32^0xFFFFFFFF; } } }

Conclusion :


Ce code n'est certainement pas le plus rapide pour effectuer un tel calcul ,
si vous avez des idées pour l 'améliorer , je suis preneur !! ^^
  • NOTE* -> le temps approximatif prevu a été calculé , par rapport aux résultats que donnait mon programme

sur mon ordi (càd un athlon1800+ avec une vieille ddr 166 , le dur pas defragmenté , 2~3 visual studio plus quelques applis qui tournaient par derriere).
J'aimerais , si certains d entre vous ont le temps , avoir les résultats sur des ordi moins puissants .
un grand merci a Capa6T pour son algo crc32 ( j en ai cherché un pendant longtemps ^^ )

Je vous rappele qu'il est déconseillé d'utiliser le crc32 en matiere de protection , pour un usage professionel utilisez plutot un hash MD5 (par ex celui dispo dans la librairie CsLib de ce site ^^ )

Codes Sources

A voir également

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.