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 :

[Conversion] Recuperation d'hexadecimale


Sujet :

C++

  1. #1
    Candidat au Club
    Inscrit en
    Septembre 2011
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Septembre 2011
    Messages : 3
    Points : 3
    Points
    3
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned char cle[5]={0x00,0x11,0xAA,0x22,0xFF};
    La solution que j'ai trouvé pour l'instant est la suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : 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
     
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    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

  4. #4
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut
    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 : 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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 x64 & Win 10 / Visual 2017 / Python 2.7 / Eclipse

  5. #5
    Candidat au Club
    Inscrit en
    Septembre 2011
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Septembre 2011
    Messages : 3
    Points : 3
    Points
    3
    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 : 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
     
    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

  6. #6
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Ya un bon paquet de fuites mémoires quand même là dedans
    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
    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é
    ...
    }

  7. #7
    Candidat au Club
    Inscrit en
    Septembre 2011
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Septembre 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Voila c'est corrigé avec des delete.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Conversion d'un fichier binaire en hexadecimale
    Par mangarance dans le forum C
    Réponses: 4
    Dernier message: 24/08/2011, 11h26
  2. recuperer l'historique de mes conversations skype
    Par GoldenEyes dans le forum Distributions
    Réponses: 1
    Dernier message: 04/09/2009, 16h12
  3. [Conversion]Données hexadecimales en decimales
    Par elcapitano dans le forum Général Java
    Réponses: 2
    Dernier message: 16/01/2005, 15h41
  4. Réponses: 2
    Dernier message: 05/06/2002, 12h29

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