IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

programme md5


Sujet :

C

  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 20
    Points : 17
    Points
    17
    Par défaut programme md5
    Bonjour,
    Pour un devoir nous devons faire la fonction md5 en C.
    Ce programme est composé de 2 fonction.
    La première padd effectue le padding du message et la seconde empreinte effectue l'empreinte du message pour lequel le padding à déjà été effectué.

    Le problème est que la fonction empreinte doit recevoir en paramètre un tableau de caractère et la taille en octet de ce tableau. Sauf que le tableau que je renvoie fait 8 octet alors qu'il devrait en faire 64 (avec l'exemple du message bonjour).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
     
    #define ROTATION(x,n) ( ((x)<<(n)) | ((x)>>(32-(n))))
     
    //Initialisation de 4 fonctions non linéaire
    int fc_F(int x,int y,int z){
    	return ((x&y)|(~x&z));
    }
    int fc_G(int x,int y,int z){
    	return ((x&z)|(y&~z));
    }
    int fc_H(int x,int y,int z){
    	return (x^y^z);
    }
    int fc_I(int x,int y,int z){
    	return (y^(x|~z));
    }
     
     
    //fonction qui effectue le padding
    char* padding(char message[], int taille_message){
     
    	const int EMPLACEMENT = 8;
    	const char un='1';
     
     
    //calcule de la taille du tableau
    	int longueur_message=strlen(message);
    	int longueur_tableau=((((longueur_message + EMPLACEMENT)/64)+1)*64);
     
     
    //copie du message
    	char *padd=malloc(sizeof(char)*longueur_tableau);
     
     
    	for(int i=0;i<longueur_message;i++){
     
    		padd[i]=message[i];
    	}
     
    	padd[longueur_message]= un;
     
     
    //calcule du nombre de zéro à ajouter
     
    	for (int i=(longueur_message+1);i<longueur_tableau;i++)
     
    	{
    		padd[i]='0';
     
    	}
     
    // Ajouter la taille du message
     
    	int x =(longueur_tableau - EMPLACEMENT);
     
    	char taille[x];
     
    	sprintf(taille,"%d",taille_message);
    	int j=x;
     
    	for(int i=0; i<strlen(taille);i++)
    	{
    		padd[j]=taille[i];
    		j++;
    	}
     
        int b=sizeof (padd); // Ici il m'affiche 8 alors qu'il doit m'afficher 64
    	printf("%d",b);
     
     
    	return (padd);
    }
     
    //fonction qui renvoie l'empreinte d'une chaine de caractères entrée en paramètre
    char* empreinte(char message[], int taille){
     
    	//initialisation de variable
    	int i, j, g, f, temp, t;
    	const long int pow_2_32=4294967296;
     
    	//initialisation de 4 variables de 32 bits
    	int A=0x01234567;
    	int B=0x89abcdef;
    	int C=0xfedcba98;
    	int D=0x76543210;
     
    	//initialisation du nombre de paquet
    	long long nb_paquet=taille/64;
    	//printf("%d\n",nb_paquet);
     
    	//initialisation de w
    	char w[16]={0};
     
    	//initialisation de r
    	int r[64]={7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
    	5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
    	4,11,16,23,4,11,16,23,4,11,16,23,4,11,26,23,
    	6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21};
     
    	//initialisation de k
    	int k[64];
     
    	for(i=0; i<64 ; i++){
    		double si=sin(i+1);
    		double abso=fabs(si);
    		double  puissance=abso*pow_2_32;
    		k[i]= (int) floor(puissance);
    		//printf("%d\n",k[i]);
    	}
     
    	//boucle paquet par paquet
    	for(j=0; j<nb_paquet ; j++){
     
    		//subdivise chaque paquet en 16 mots de 32 bits
    		for (i=0; i<16 ;i++){
    			w[i]=message[j*16+i];
    			//printf("%d\n",w[i]);
    		}
     
    		//sauvegarde des variables
    		int AA=A;
    		int BB=B;
    		int CC=C;
    		int DD=D;
     
    		//boucle principal
    		for(i=0; i<64 ;i++){
    			if((i>=0) && (i<=15)){
    				f=fc_F(BB,CC,DD);
    				g=i;
    			}
    			else if((i>=16) && (i<=31)){
    				f=fc_G(BB,CC,DD);
    				g=(5*i+1)%16;
    			}
    			else if((i>=32) && (i<=47)){
    				f=fc_H(BB,CC,DD);
    				g=(3*i+5)%16;
    			}
    			else{
    				f=fc_I(BB,CC,DD);
    				g=(7*i)%16;
    			}
    			temp=DD;
    			DD=CC;
    			CC=BB;
    			BB=ROTATION(AA+f+k[i]+w[g],r[i])+BB;
    			AA=temp;
    		}
     
    		//reassignement des variables
    		A+=AA;
    		B+=BB;
    		C+=CC;
    		D+=DD;
    	}
    	// convertion des registres en chaines de caractères
    	char *emp=malloc(sizeof(char)*32);
    	sprintf(emp, "%x", A);
    	char ch1[24];
    	sprintf(ch1, "%x", B);
    	char ch2[16];
    	sprintf(ch2, "%x", C);
    	char ch3[8];
    	sprintf(ch3, "%x", D);
     
     
    	strcat(emp,strcat(ch1,strcat(ch2,ch3)));
     
    	return emp;
     
    }
     
     
    int main(){
    	char message[]="bonjour";
    	int taille = sizeof(message);
    	char *pad=padding(message, taille);
     
    	int taille_empreinte=sizeof(pad)*8;
    	char *hachage=empreinte(pad,taille_empreinte);
    	printf("%s \n",hachage);
    	free(pad);
    	free(hachage);
     
    }

    Voilà ! Pouvez-vous m'aider ??

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 673
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 673
    Points : 10 683
    Points
    10 683
    Par défaut
    Citation Envoyé par e5mm100 Voir le message
    Sauf que le tableau que je renvoie fait 8 octet alors qu'il devrait en faire 64 (avec l'exemple du message bonjour).
    int b=sizeof (padd); // Ici il m'affiche 8 alors qu'il doit m'afficher 64.
    l'erreur de débutant.

    La taille d'1 pointeur c'est soit 4 (en 32 bits) soit 8 (en 64 bits).
    Tu ne peux pas connaitre la taille d'1 tableau sans transmettre sa taille (à moins d'être dans le même fichier source/ fonction avec la formule sizeof(tab) / sizeof( tab[0] ) si je ne me trompe pas )

  3. #3
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 20
    Points : 17
    Points
    17
    Par défaut
    merci pour votre réponse mais du coup si j'ai bien compris au moment du return de la fonction de padd je dois écrire
    return (padding,longueur_tableau);
    Sauf que le problème c'est que ma fonction empreinte est un fontion de type char*

  4. #4
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 319
    Points : 346
    Points
    346
    Par défaut
    Houlà !!

    Le return ne retourne qu'un seul type de données (standard, ou un type que tu aurais définis préalablement au moyen de typedef).

    Donc le return (padding,longueur_tableau); ça ne fonctionnera pas au niveau de l'analyseur syntaxique et tu auras une erreur à la compilation.

    Si tu dois retourner l'ensemble, j'ai pas tout lu pour dire la vérité, il faudrait alors changer ton type de retour en une structure contenant la valeur de padding et la valeur de longueur_tableau.

    Du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct s_valeurs
    {
     ... _padding;   // ... pour le type de padding
     ... _longueur; // ... pour le type de longueur_tableau
    }t_valeurs;
    ...dans ta fonction tu remplaces char* par t_valeurs...

    ...dans le corps de la fonction tu crées un "objet" t_valeurs auquel tu assignerais les valeurs aux champs respectifs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    t_valeurs tmpValeurs={padding,longueur_tableau};
    return tmpValeurs;
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (t_valeurs){padding,longueur_tableau};
    ...je sais pas si ma vision pourrait t'aider...

    [EDIT]
    Si tu dois connaître la taille (en caractères) d'un tableau de caractères (char*) ce serait strlen() qu'il faudrait utiliser et non sizeof() qui n'indique que la taille du type.

  5. #5
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 20
    Points : 17
    Points
    17
    Par défaut
    Bonjour j'ai pris en compte en compte votre remarque et j'ai modifier mon programme pour que ma permière fonction renvois une structure avec la taille et le tableau. Cependant ça ne marche toujours pas.

    Je pense que le problème vient de la deuxième fonction. Tout marche mais je n'ai pas la bonne empreinte à la fin et je ne sais pas pourquoi .


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
     
    #define ROTATION(x,n) ( ((x)<<(n)) | ((x)>>(32-(n))))
     
    //Initialisation de 4 fonctions non linéaire
    int fc_F(int x,int y,int z){
    	return ((x&y)|(~x&z));
    }
    int fc_G(int x,int y,int z){
    	return ((z&x)|(~z&y));
    }
    int fc_H(int x,int y,int z){
    	return (x^y^z);
    }
    int fc_I(int x,int y,int z){
    	return (y^(x|(~z)));
    }
     
    typedef struct Tableau
    {
        int longueur_tableau;
        char *padding;
    }Tableau;
     
    //fonction qui effectue le padding
    Tableau padd(char message[], int taille_message){
     
    	Tableau var;
     
    	const int EMPLACEMENT = 8;
    	const char un='1';
     
    //calcule de la taille du tableau
    	int longueur_message=strlen(message);
    	var.longueur_tableau=((((longueur_message + EMPLACEMENT)/64)+1)*64);
     
     
     
    //copie du message
    	var.padding=malloc(sizeof(char)*var.longueur_tableau);
     
     
    	for(int i=0;i<longueur_message;i++){
     
    		var.padding[i]=message[i];
    	}
     
    	var.padding[longueur_message]= un;
     
     
    //calcule du nombre de z�ro � ajouter
     
    	for (int i=(longueur_message+1);i<var.longueur_tableau;i++)
     
    	{
    		var.padding[i]='0';
     
    	}
     
    // Ajouter la taille du message
     
    	int x =(var.longueur_tableau - EMPLACEMENT);
     
    	char taille[x];
     
    	sprintf(taille,"%d",taille_message);
    	int j=x;
     
    	for(int i=0; i<strlen(taille);i++)
    	{
    		var.padding[j]=taille[i];
    		j++;
    	}
     
    	int a=sizeof(var.padding);
    	printf("%d",a);
     
     
    	return var;
    }
     
     
    //fonction qui renvoie l'empreinte d'une chaine de caractères entrée en paramètre
    char* empreinte(char message[], int taille){
     
    	//initialisation de variable
    	int i, j, g, f, temp;
    	const long long int pow_2_32=4294967296;
     
    	//initialisation de 4 variables de 32 bits
    	int A=0x01234567;
    	int B=0x89abcdef;
    	int C=0xfedcba98;
    	int D=0x76543210;
     
    	//initialisation du nombre de paquet
    	long long nb_paquet=taille/64;
    	//printf("%d\n",nb_paquet);
     
    	//initialisation de w
    	int w[16]={0};
     
    	//initialisation de r
    	int r[64]={7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
    	5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
    	4,11,16,23,4,11,16,23,4,11,16,23,4,11,26,23,
    	6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21};
     
    	//initialisation de k
    	int k[64];
     
    	for(i=0; i<64 ; i++){
    		double si=sin(i+1);
    		double abso=fabs(si);
    		double  puissance=(abso*pow_2_32);
    		k[i]= (int) floor(puissance);
    		//printf("%d\n",k[i]);
    	}
     
    	//boucle paquet par paquet
    	for(j=0; j<nb_paquet ; j++){
     
    		//subdivise chaque paquet en 16 mots de 32 bits
    		for (i=0; i<16 ;i++){
    			w[i]=message[j*16+i];
    			printf("%d\n",w[i]);
    		}
     
    		//sauvegarde des variables
    		int AA=A;
    		int BB=B;
    		int CC=C;
    		int DD=D;
     
    		//boucle principal
    		for(i=0; i<64 ;i++){
    			if((i>=0) && (i<=15)){
    				f=fc_F(BB,CC,DD);
    				g=i;
    			}
    			else if((i>=16) && (i<=31)){
    				f=fc_G(BB,CC,DD);
    				g=((5*i)+1)%16;
    			}
    			else if((i>=32) && (i<=47)){
    				f=fc_H(BB,CC,DD);
    				g=((3*i)+5)%16;
    			}
    			else{
    				f=fc_I(BB,CC,DD);
    				g=(7*i)%16;
    			}
    			temp=DD;
    			DD=CC;
    			CC=BB;
    			BB=ROTATION(AA+f+k[i]+w[g],r[i])+BB;
    			AA=temp;
    		}
     
    		//reassignement des variables
    		A+=AA;
    		B+=BB;
    		C+=CC;
    		D+=DD;
    	}
    	// convertion des registres en chaines de caractères
    	char *emp=malloc(sizeof(char)*32);
    	sprintf(emp, "%x", A);
    	char ch1[24];
    	sprintf(ch1, "%x", B);
    	char ch2[16];
    	sprintf(ch2, "%x", C);
    	char ch3[8];
    	sprintf(ch3, "%x", D);
     
     
    	strcat(emp,strcat(ch1,strcat(ch2,ch3)));
     
    	return emp;
     
    }
     
     
    int main(){
    	char message[]="bonjour";
    	int taille = sizeof(message);
    	Tableau tab = padd(message,taille);
     
     
     
    	char *hachage=empreinte(tab.padding,tab.longueur_tableau);
    	printf("%s \n",hachage);
    	free(hachage);
    }

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 726
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 726
    Points : 31 046
    Points
    31 046
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par e5mm100 Voir le message
    Je pense que le problème vient de la deuxième fonction. Tout marche mais je n'ai pas la bonne empreinte à la fin et je ne sais pas pourquoi .


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	const char un='1';
     
    	for(int i=0;i<longueur_message;i++){
     
    		var.padding[i]='0';
    	}
    Je pense qu'un des soucis vient d'ici. Il ne faut pas confondre les caractères '0' ou '1' (respectivement 48 ou 49, sur 8 bits donc 00110000 et 00110001) avec des bits 0 ou 1 (donc 0 ou 1 sur un unique bit).
    Tu devrais utiliser memset() et memcpy() pour optimiser tes opérations de remplissage de zone...

  7. #7
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 950
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 950
    Points : 5 667
    Points
    5 667
    Par défaut
    Bonjour,

    Je vois que tu as créé une fonction pour chaque partie du calcul de md5.

    Ayant réalisé ce programme depuis longtemps, je peux te garantir que c'est beaucoup plus lent que faire un programme "sale", qui enchaîne tous les calculs dans une même fonction.

    La différence de temps de calcul est spectaculaire !

    À l'époque, j'avais testé ça, car la version "propre" me donnait des temps de calculs bien trop grands par rapport à ce que je lisais sur les sites de programmation.


  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 726
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 726
    Points : 31 046
    Points
    31 046
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par droggo Voir le message
    À l'époque, j'avais testé ça, car la version "propre" me donnait des temps de calculs bien trop grands par rapport à ce que je lisais sur les sites de programmation.
    Peut-être en remplaçant les fonctions par des macros (voire des inline)...

  9. #9
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2020
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2020
    Messages : 20
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Bonjour

    Je pense qu'un des soucis vient d'ici. Il ne faut pas confondre les caractères '0' ou '1' (respectivement 48 ou 49, sur 8 bits donc 00110000 et 00110001) avec des bits 0 ou 1 (donc 0 ou 1 sur un unique bit).
    Tu devrais utiliser memset() et memcpy() pour optimiser tes opérations de remplissage de zone...

    Bonjour j'ai pris en note vos conseilles et j'ai corrigé mon programme, il marche cependant il y a un dernier problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    #include <stdint.h>
     
     
    #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
     
    typedef struct Tableau
    {
         int longueur_tableau;
         char *padding;
    }Tableau;
     
    Tableau padd(char message[], int taille_message){
     
         Tableau var;
         const int EMPLACEMENT = 8;
         const char UN = (unsigned char) 0x80;
         int x;
     
         // calcule taille tableau 
         var.longueur_tableau = ((((taille_message + EMPLACEMENT) / 64) +1) * 64);
     
         //initialisation tableau 
         var.padding = calloc(var.longueur_tableau, sizeof(char));
         memcpy(var.padding, message, taille_message);
     
         //ajout du 1
         var.padding[taille_message] = UN;
     
         // calcule taille du message a ajouter 
         x=(var.longueur_tableau-EMPLACEMENT);// je pense que le problème vient d'ici
         var.padding[x] = 8*taille_message;
     
         return var;
    }
     
     
    //fonction qui renvoie l'empreinte d'une chaine de caract�res entr�e en param�tre
    char* empreinte(char message[], int taille){
     
         //initialisation de variable
         int i, j, temp;
         int *w;
     
         uint8_t *p;
     
         //uint32_t f, g;
     
         int A=0x67452301;
         int B=0xefcdab89;
         int C=0x98badcfe;
         int D=0x10325476;
     
       //initialisation de 4 variables qui serviront de sauvegarde aux buffers
         int AA;
         int BB;
         int CC;
         int DD;
         //initialisation du nombre de paquet
         long long nb_paquet=taille/64;
     
         //initialisation de w qui sera initialiser par 16 mots de 32bits(le tableau w �quivaut � un paquet de 512 bits)
     
     
         int r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
                    5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,
                    4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
                    6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
     
     
         int k[] = {
             0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
             0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
             0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
             0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
             0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
             0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
             0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
             0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
             0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
             0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
             0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
             0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
             0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
             0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
             0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
             0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
     
     
         for(j=0; j<nb_paquet ; j++){
     
             w = (int *) (message+j*64);
     
             AA=A;
             BB=B;
             CC=C;
             DD=D;
     
             for(i=0; i<64 ;i++){
     
                 uint32_t f, g;
                 int ou = 0;
     
                 if((i>=0) && (i<=15)){
                     f=((BB&CC)|((~BB)&DD));
                     g=i;
                     ou = 1;
                 }
                 else if((i>=16) && (i<=31)){
                     f=((DD&BB)|((~DD)&CC));
                     g=((5*i)+1)%16;
                     ou = 2;
                 }
                 else if((i>=32) && (i<=47)){
                     f=(BB^CC^DD);
                     g=((3*i)+5)%16;
                     ou = 3;
                 }
                 else{
                     f= CC ^ (BB|(~DD));
                     g=(7*i) % 16;
                     ou = 4;
     
                 }
     
     
                 temp=DD;
                 DD=CC;
                 CC=BB;
                 BB=LEFTROTATE(AA+f+k[i]+w[g],r[i])+BB;
                 AA=temp;
     
     
             }
     
             //reassignement des variables � chaque fin de paquet
             A+=AA;
             B+=BB;
             C+=CC;
             D+=DD;
         }
     
         p=(uint8_t *)&A;
         char *emp=malloc(sizeof(char)*32);
         sprintf(emp, "%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
          p=(uint8_t *)&B;
         char ch1[32];
         sprintf(ch1, "%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
          p=(uint8_t *)&C;
         char ch2[32];
         sprintf(ch2, "%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
          p=(uint8_t *)&D;
         char ch3[32];
         sprintf(ch3, "%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
     
     
       //concatenation des chaines en une seule
         strcat(emp,ch1);
         strcat(emp,ch2);
         strcat(emp,ch3);
     
     
         return emp;
     
    }
     
     
    int main(){
     
        FILE *fichierMess;
        fichierMess=fopen("message.txt","r");
     
        char message[1000];
        fgets(message, 1000, fichierMess);
     
        int taille = strlen(message);
     
        Tableau tab = padd(message,taille);
     
     
     
        char *hachage=empreinte(tab.padding,tab.longueur_tableau);
     
        printf("L'empreinte de %s est : %s \n",message,hachage);
     
        free(hachage);
        free(tab.padding);
        fclose(fichierMess);
    }

    lorsque mon fichier contient moins de 32 caractère tout marche et l'empreinte est bonne, par contre quand c'est plus de 32 caractère là ce n'est pas bon et je ne comprend pas pourquoi !

  10. #10
    Membre averti

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 319
    Points : 346
    Points
    346
    Par défaut
    "emp" semble limité à 32 caractères... est-ce normal ?

    pareil pour les chaînes chX[32]... je regarderais de ce côté... à mon avis il y a un "tronquage" quelque part.

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 726
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 726
    Points : 31 046
    Points
    31 046
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par hurukan Voir le message
    "emp" semble limité à 32 caractères... est-ce normal ?
    Oui, c'est la variable qui récupère le calcul (empreinte) du md5 et elle doit bien être à 32 caractères (enfin en réalité elle devrait être à [32+1] pour avoir aussi la place pour le '\0' qui doit terminer la string mais ce n'est pas ça qui fait foirer le calcul).
    Et s'il y avait tronquage, alors la signature d'un fichier de 33 caractères serait la même que celle d'un fichier de 32 or ce n'est pas le cas.

    Citation Envoyé par hurukan Voir le message
    pareil pour les chaînes chX[32]... je regarderais de ce côté
    Effectivement là il y a un petit souci mais ce n'est pas celui auquel tu penses. Regarde mieux et je suis sûr que tu tomberas d'accord sur le fait qu'elles pourraient en fait être simplement des chX[9] (ou plus habituellement, quand on crée des strings et qu'on veut montrer qu'on a pensé à tout, être des chX[8+1])

    Citation Envoyé par e5mm100 Voir le message
    lorsque mon fichier contient moins de 32 caractère tout marche et l'empreinte est bonne, par contre quand c'est plus de 32 caractère là ce n'est pas bon et je ne comprend pas pourquoi !
    Pour moi, le souci ne vient pas du calcul de l'empreinte. Car que ce soit 32 ou 33 octets cette boucle for(j=0; j<nb_paquet ; j++) ne change pas et ne fait qu'une seule itération. Donc si le calcul était faux, il serait faux aussi pour 32 (et il est bon, j'ai vérifié). A mon avis, le souci vient encore du padding mais j'ai la flemme de l'examiner. Simplement j'ai testé sur un fichier de 184 caractères (1472 bits), normalement le padding aurait dû compléter jusqu'au multiple de 512 bits suivant (donc 1536 bits soit 192 caractères) or quand j'affiche "taille", il me répond 256.

    Ceci dit, j'ai apprécié le const char UN = (unsigned char) 0x80 car j'ai trouvé ça particulièrement brillant (bien que particulièrement mal écrit => const unsigned char UN = 0x80 ). Simplement je pense que peut-être les 7 "zéros" qui suivent n'ont peut-être pas été ou mal été comptabilisés.
    Je pense que rajouter une fonction permettant d'afficher (débugguer) le contenu complet en binaire (ou hexa) de la zone "paddée" ne serait pas du temps perdu.

    Accessoirement je conseillerais de ne pas bouder le "unsigned". Outre que les copies peuvent être plus rapides (pas de temps perdu à regarder si le bit de signe vaut "1" ce qui oblige à l'étendre quand on copie une valeur ayant cette particularité dans un type plus large), cela permet aussi des plages de valeur positives plus importantes. Par exemple pour "nb_paquet" ça peut aider.

    Petit détail: t'es sûr pour tes 3 strcat() à suivre ? Tu n'as pas pensé que sprintf() que tu utilises allègrement 3 lignes juste au dessus pouvait aussi servir ici ? Dommage, cela annule la brillante idée du const char UN = (unsigned char) 0x80...
    Et enfin ces "%2.2x" que je verrais plutôt écrits "%02x"...

Discussions similaires

  1. Aide avec mon programme decryptage MD5
    Par hacker59 dans le forum VB.NET
    Réponses: 0
    Dernier message: 19/05/2013, 20h20
  2. Problème programmation md5
    Par deltabweb dans le forum Windows
    Réponses: 15
    Dernier message: 20/01/2008, 19h06
  3. Programme de boot qui passe la main à Windows
    Par Bob dans le forum Assembleur
    Réponses: 7
    Dernier message: 25/11/2002, 03h08
  4. [Kylix] Probleme d'execution de programmes...
    Par yopziggy dans le forum EDI
    Réponses: 19
    Dernier message: 03/05/2002, 14h50
  5. [Kylix] icone associée à un programme
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 22/03/2002, 09h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo