Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++ > Débuter
Débuter Forum d'entraide pour débuter en langage de programmation C++. Avant de poster : cours d'initiation au C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 04/01/2013, 17h16   #1
crackos77
Invité de passage
 
Inscription : septembre 2011
Messages : 4
Détails du profil
Informations forums :
Inscription : septembre 2011
Messages : 4
Points : 1
Points : 1
Par défaut [Conversion] Recuperation d'hexadecimale

Salut à tous,

Je fréquente le forum depuis un petit moment sans avoir poster jusqu'à présent mais aujourd'hui je suis face à deux problèmes et je viens solliciter votre aide.

Voici la situation:
1er problème :
Mon code doit simuler une authentification avec des calculs de chiffrement (triple DES,...). Je ne rentrerai pas trop dans les détails car la n'est pas le problème. Afin de rendre le programme dynamique je demande à l'utilisateur de saisire les clés de chiffrements qui seront utilisées plus tard. Je précise que j'utilise la librairie openssl pour effectuer les calculs.

J'essaie donc de récupérer une clé de chiffrement depuis le terminal et c'est là qu'intervient le problème.

La clé est au format hexadécimale. C'est à dire de la forme "0x0011AA22FF". Elle sera stockée dans un unsigned char[] sous la forme suivante:
Code :
unsigned char cle[5]={0x00,0x11,0xAA,0x22,0xFF};
La solution que j'ai trouvé pour l'instant est la suivante:
Code :
1
2
3
4
5
6
7
 
    int number;
    printf("\nEnter your master key byte by byte:\n");
	for(int i=0;i<sizeof(masterkey);i++){
		scanf("%x",&number); //l'utilisateur saisie 2 digits a la fois (ex. 41)
		masterkey[i]=number; //on stocke les digits dans notre tableau (à l'indice i il y aura donc 0x41 qui correspond au caractère 'A' en ASCII)
	}
Ce code est fonctionnel mais n'est pas pratique car il oblige l'utilisateur à saisir les digits deux par deux et de valider à chaque fois entre.
La solution parfaite serait que l'utilisateur puisse taper sa clé en une fois, que celle-ci soit considérée non pas comme un string mais comme une valeur en hexa que l'on viendrait parser dans le tableau d'unsigned char.

2eme problème
Maintenant, afin de réaliser les mêmes opérations, le second objectif est de mettre en place une interface graphique avec Windows Form en C++ sous Visual Studio.
J'ai voulu dans un premier temps utiliser ma solution (bien qu'un peu bancale (qui a dit beaucoup???)) combinée avec des textbox mais celle-ci n'est pas applicable car le texte est récupéré dans ces dernières n'est pas interprétable en hexadécimale car il est automatiquement récupéré dans le champ Text de la textbox en string.
J'ai du coup essayé de convertir ce string avec ceci:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
private: System::Void textBox1_TextChanged(System::Object^  sender, System::EventArgs^  e) {
			 System::String^ txt;
			 //std::string txt;
			 if(textBox1->MaxLength==textBox1->TextLength){
				txt=textBox1->Text;
				label1->Text=System::Convert::ToString(mafonction(txt));
				textBox2->Select();
 
				//sscanf(&masterkey,"%x",&val);
			 }
 
//fonction située dans un autre fichier .cpp
char mafonction(System::String^ val){
	char masterkey;
	System::String^ res;
	sscanf(&masterkey,"%x",&val);
	return masterkey;
}
sans aucun succès.

Avec ce "joli" morceau de code j'ai le droit à l'erreur suivante:
Code :
1
2
3
Une exception non gérée du type 'System.Runtime.InteropServices.MarshalDirectiveException' s'est produite dans test1.exe
 
Informations supplémentaires*: Cannot marshal 'parameter #3': Pointers cannot reference managed objects.  Use ByRef instead.

La démarche est donc très archaïque avec cette solution.

J’espère avoir été assez clair dans mes explications afin que chacun puisse comprendre mon problème. Sinon n'hésitez pas à me demander des précision

Merci par avance,
Crackos

Ps: Pour info, je code en C++ (malgré que j'utilise plus du C qu'autre chose) et ce sous Visual Studio, voilou
crackos77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2013, 19h42   #2
Neckara
Rédacteur
 
Avatar de Neckara
 
Homme Denis
Étudiant
Inscription : décembre 2011
Messages : 2 579
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Loire (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : décembre 2011
Messages : 2 579
Points : 6 996
Points : 6 996
Envoyer un message via MSN à Neckara Envoyer un message via Skype™ à Neckara
Bonjour,

Pour ton problème de clé, tu peux utilisé fgets pour récupérer une chaîne de caractère (solution C).
Ou std::string x; std::cin >> x; (solution C++).

Ensuite pour la conversion, tu peux utiliser sscanf (solution C) ou le faire à la main avec :
Code :
1
2
3
4
5
6
char hexa;
char premierQuartet;
char secondQuartet;
premierQuartet -= (premierQuartet <= '9' ? '0':'A'-10);
secondQuartet -= (secondQuartet <= '9' ? '0':'A'-10);
hexa = premierQuartet * 16 + secondQuartet;
Je ne sais pas s'il existe un équivalent en C++ de dans (petit edit) la bibliothèque standard.
__________________
Recherche devs C++ motivés et sérieux pour Last Dungeon.

Chaîne Youtube : Vidéos

Ma page DVP : http://neckara.developpez.com/
Neckara est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/01/2013, 12h45   #3
Lintel-oo
Membre habitué
 
Homme
Étudiant
Inscription : avril 2011
Messages : 239
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2011
Messages : 239
Points : 128
Points : 128
Comme le dit neckara, pourquoi utiliser un tableau de char ?
Les string sont fait pour cela ! Puisque tu peux accéder à chacun de ses éléments comme tu le ferais avec un tableau.

Maintenant tout dépend de ce que tu veux faire et afficher, mais utiliser des string est beaucoup plus aisé que d'utiliser des tableaux de char
Lintel-oo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2013, 09h39   #4
Captain'Flam
Membre habitué
 
Avatar de Captain'Flam
 
anciennement "sopsag"
Inscription : février 2011
Messages : 118
Détails du profil
Informations personnelles :
Nom : anciennement "sopsag"

Informations forums :
Inscription : février 2011
Messages : 118
Points : 138
Points : 138
Salut crackos77, je te fais don de ma super routine écrite il y a quelques années et qui résout ton problème n°1 :
Code :
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
int hexa_value ( char h , BOOL * error )
    {
    int res = 0 ;
         if (h <  '0') *error = TRUE ;
    else if (h <= '9') res = h-'0' ;
    else if (h <  'A') *error = TRUE ;
    else if (h <= 'F') res = h-'A'+10 ;
    else if (h <  'a') *error = TRUE ;
    else if (h <= 'f') res = h-'a'+10 ;
    else *error = TRUE ;
    return( res ) ;
    }
 
int hexa2bytes ( BYTE * buffer , int buffer_size , const char * str )
    {
    const char *s = str ;
    BYTE *p       = buffer ;
    BYTE *end     = buffer+buffer_size ;
 
    for (; (p <= end) && *s ; s += 2 , p++ )
        {
        BOOL error = FALSE ;
        *p = (BYTE)( hexa_value( s[0],&error )*16 + hexa_value( s[1],&error )) ;
        if (error) return -1 ;
        }
 
    return (int)(p-buffer) ;
    }
(je l'ai un peu adapté à la volée, du coup je ne garantis pas qu'elle compile, mais l'idée y est).
ex
Code :
1
2
3
4
5
BYTE buffer [5] ;
int res ;
res = hexa2bytes( buffer,5,"cafe" ) ; // res == 2 ; buffer[0] == 0xCA ; buffer[1] == 0xFE
res = hexa2bytes( buffer,1,"cafe" ) ; // res == 1 ; buffer[0] == 0xCA ==> 0xFE est perdu !
res = hexa2bytes( buffer,5,"cage" ) ; // res == -1 ; ==> erreur !
Etant complément ignare en matière d'interface Windoz, je n'aborderais même pas le problème n°2.

tcho !
__________________
Captain'Flam
anciennement Sopsag, aka Hadrien
Win seven 64 / Visual 2010 / Python 2.7 / Eclipse
Captain'Flam est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2013, 15h14   #5
crackos77
Invité de passage
 
Inscription : septembre 2011
Messages : 4
Détails du profil
Informations forums :
Inscription : septembre 2011
Messages : 4
Points : 1
Points : 1
Par défaut Solution!!!

Salut tout le monde,

Tout d'abord merci pour vos réponses et notamment à Captain'Flam.
Je me suis permis d'intégrer ta solution et en l'adaptant un petit peu cela fonctionne parfaitement .

Voici un petit aperçu du résultat:


Je communique mon morceau de code pour ceux qui pourraient en avoir besoin:
Code :
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
 
int hexa_value2 ( unsigned char h , bool * error ){
    int res = 0 ;
         if (h <  '0') *error = true ;
    else if (h <= '9') res = h-'0' ;
    else if (h <  'A') *error = true ;
    else if (h <= 'F') res = h-'A'+10 ;
    else if (h <  'a') *error = true ;
    else if (h <= 'f') res = h-'a'+10 ;
    else *error = true ;
    return( res ) ;
}
 
std::string hexa2bytes2(std::string str)
{
    int i,j=0;
	string newstr="";
	char p;
 
	char* buffer= new char[str.size()+1];
	unsigned char* final= new unsigned char[(str.size()/2)];
 
	unsigned char * writable = new unsigned char[17];
	std::copy(str.begin(), str.end(), writable);
	writable[str.size()] = '\0'; // don't forget the terminating 0
 
 
    for (i=0; i<(str.size()/2) ; i++)
    {
		bool error = false ;
        final[i] = (unsigned char)( hexa_value2( writable[j],&error )*16 + hexa_value( writable[j+1],&error )) ;
        j=j+2;
		if (error) return 0 ;
    }
 	for(i = 0; i<str.size()/2; i++)
		newstr += final[i];
	delete[] writable;
    return (newstr) ;
}
 
System::String^ mafonction(System::String^ str)
{
	int res ;
	string tmp;
	MarshalString(str,tmp);
	unsigned char *buffer2= new unsigned char[tmp.size()];
	int cpt;
 
	tmp = hexa2bytes2(tmp) ;
	String^ str2 = gcnew String(tmp.c_str());
	return str2;
}
 
bool onlyhexvalue(System::String^ str){
	string tmp;
	MarshalString(str,tmp);
	unsigned char *buffer= new unsigned char[tmp.size()];
	memcpy(buffer,tmp.c_str(),tmp.size());
	int tmpsize = tmp.size();
	for(int i=0;i<tmp.size();i++){
		if (isxdigit(buffer[i])==0)
		{
			return false;
		}
	}
 
	return true;
}
Voila Voila, en vous remerciant pour votre aide,
Crackos
crackos77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/01/2013, 00h15   #6
Iradrille
Membre éprouvé
 
Homme
Étudiant
Inscription : juin 2012
Messages : 263
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : juin 2012
Messages : 263
Points : 443
Points : 443
Ya un bon paquet de fuites mémoires quand même là dedans
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
std::string hexa2bytes2(std::string str) { // passage par ref constante préférable
...
	char* buffer= new char[str.size()+1]; // jamais libéré
	unsigned char* final= new unsigned char[(str.size()/2)]; // jamais libéré
	unsigned char * writable = new unsigned char[17]; // pas libéré si erreur
	// et pourrait être unsigned char writtable[17]; vu que la taille est connue
...
 
	for(i = 0; i<str.size()/2; i++)
		newstr += final[i]; // peut être dans la 1ere boucle
...
}
 
System::String^ mafonction(System::String^ str) {
...
	unsigned char *buffer2= new unsigned char[tmp.size()]; // jamais libéré
...
}
 
bool onlyhexvalue(System::String^ str) {
...
	unsigned char *buffer= new unsigned char[tmp.size()]; // jamais libéré
...
}
Iradrille est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/01/2013, 10h03   #7
crackos77
Invité de passage
 
Inscription : septembre 2011
Messages : 4
Détails du profil
Informations forums :
Inscription : septembre 2011
Messages : 4
Points : 1
Points : 1
Voila c'est corrigé avec des delete.
crackos77 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 14h41.


 
 
 
 
Partenaires

Hébergement Web