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 :

Hex to string


Sujet :

C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 23
    Points : 30
    Points
    30
    Par défaut Hex to string
    Bonjour, voilà tout est dans le titre, je voudrais bien pouvoir créé une mini application console qui puisse traiter en argument des chaines de caractères de ce type: 646576656c6f7070657a2e6e6574
    Ici je vais pas travailler avec un argument mais directement dans une variable
    la même chose que sur cette url en gros Hex to string

    J'ai réussi partiellement ce que je voulais faire grace a l'aide de personne sur irc mais il y a des bug. je début en C depuis quelque jours.

    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
     
    #include <stdio.h>
    #include <math.h>
    #include <windows.h>
     
    // Méthode simple de conversion (sans vérification !)
    // '0' représente le premier caractère (selon la table ascii) qui est un nombre
    //	Sa valeur est 48, si par exemple nous avons '1' (qui vaut 49)
    // '1' - '0' = 1  ( 49 - 48 = 1 )
    int NombreASCII_2_Entier( char ascii ) {
    	return ascii - '0';
    }
     
    // Méthode de conversion de base : http://visualcplus.blogspot.com/2006/03/hexadecimal-2-decimal.html
    int ConvertionBase( int nombre, int baseOrigine, int baseFinal ) {
    	int entier = 0,
    	lenHexa = log10( (double)nombre );
     
    	for( int i = 0; i < lenHexa + 1; i++ ) {
    		int dizaines = pow((double)baseFinal,lenHexa - i);
     
    		entier += (int)(nombre / dizaines) * pow( (double)baseOrigine, lenHexa - i );
    		nombre %= dizaines;
    	}
     
    	return entier;
    }
     
    int main() {
     
       char chaineHexa[] = "646576656c6f7070657a2e6e6574";
     
        char tmpStrHexa[2];
     
        char tmpChar;
     
        int lenChaineHexa = strlen( chaineHexa ), q = 0;
     
        char buffer[(lenChaineHexa/2) * sizeof(char) +1];
     
        if (buffer != NULL)
        {
            for( int i = 0; i < lenChaineHexa; i += 2 ) {
                // Copie les deux caractères selon la position actuel
                // chaineHexa + i est équivalent à chaineHexa[i]. Ici j'utilise l'adition étant donnée
                //	que chaineHexa est à la base qu'une simple adresse en mémoire, et que nous voulons
                //	l'adresse du Nième élément (ou N est la variable i ici)
                memcpy( tmpStrHexa, chaineHexa + i , sizeof( *chaineHexa ) * 2 );
                // Convertie le code ASCII en entier
                tmpChar = NombreASCII_2_Entier( tmpStrHexa[0] ) * 10 + NombreASCII_2_Entier( tmpStrHexa[1] );
                // Convertie la valeur hexa (entrée par l'utilisateur) en entier
                tmpChar = ConvertionBase( tmpChar, 16, 10 );
                printf("--> %c%c --> %c\n", tmpStrHexa[0], tmpStrHexa[1], tmpChar);
                // %c affiche un caractère
                //printf("%c\n", tmpChar );
                 buffer[q] = tmpChar;
     
                q++;
            }
            buffer[q] = '\0';
            printf("Text: %s\n", buffer);
     
        }
     
    }
    Voilà, au lieu de m'afficher " Text: developpez.net " il m'affiche que la moitié du résultat (sa dépend des caractères). je sais vraiment pas le problème.
    car je voudrais que sa fonctionne aussi bien que si j'aurais fait directement dans une var
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char dev[] = "\x64\x65\x76\x65\x6c\x6f\x70\x70\x65\x7a\x2e\x6e\x65\x74";
    ce qui m'affichera bien le text.
    Je penses que c'est tout a fait possible si ce site peu le faire, en C aussi.
    Malgré ça j'ai eu quelques difficultés à trouvés des informations a ce sujet sur internet.

    Merci à vous

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Bonsoir,

    Ouille ! Misère ! Tu te donnes beaucoup de mal pour pas grand chose. Il n'en faut pas tant pour écrire un convertisseur hexadécimal ↔ A.S.C.I.I.

    Globalement, on peut dire que tu tentes autant que tu peux de respecter les standards, c'est déjà bien. Sur le fond, Il y a déjà une faille dans ta fonction NombreASCII_2_Entier() : retirer '0' fonctionne bien ... pour les chiffres de '0' à '9' ! Les lettres 'a' à 'f' ne sont pas consécutives à ces chiffres. Il faut donc traiter ces deux cas séparément.

    Ensuite, tu n'as absolument pas besoin de passer par les logarithmes et exponentiations pour changer de base (et heureusement). De toutes façons, le tout est stocké en binaire dans la mémoire de ton ordinateur. En fait, de la même façon qu'en décimal, tu multiplies par dix chaque fois que tu changes de colonnes, en hexadécimal, tu vas multiplier par 16. Exemples :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    6c =  6 × 16 + 12 = 108 (car C en hexadécimal = 12 en décimal)
    f9 = 15 × 16 +  9 = 249 (car F en hexadécimal = 15 en décimal)
    Donc, tu n'as qu'à corriger NombreASCII_2_Entier() pour qu'elle prenne bien en charge les chiffres hexadécimaux. Ensuite, tu t'en sers pour lire la valeur du premier chiffre, tu multiplies cette valeur par seize, et tu lui ajoutes la valeur du second chiffre et tu n'as plus qu'à afficher le caractère avec putchar().

    Tu peux retirer tous tes pow(), tes log10() et tes double.

    Bonne chance.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 23
    Points : 30
    Points
    30
    Par défaut
    Merci pour ton post, on ma proposer cette solution de passé par les ascii pour récupérer le hex au final. s'il faut je peux recommencer mais je devrais avoir le résultat final comme http://www.string-functions.com/hex-string.aspx
    donc une char var[] = "646576656c6f7070657a2e6e6574"; qui dois me retourner en printf("valeur: %s - fin\n", hex); // écrit valeur: developpez.net - fin

    je débutes vraiment et j'ai pas vraiment compris ton calcule, je dois modifier quel partie du code ?
    Car j'ai fait plusieurs méthode pour arriver a un résultat et j'ai tjs eu des problèmes avec des lettres entre a-z alors que sa devrais gérer tout les caractères possible de la même manière que char mot[] = "\x..\x..";

  4. #4
    Membre régulier Avatar de J4e8a16n
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 271
    Points : 119
    Points
    119
    Par défaut
    Mon 2 sous:


    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
    int hx2car (char in, char in2)
    {
    int i, j;
    char seize[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
     
    for (i=0;i<16 ;i++ )
                 if(in == seize[i]){ i<<= 4;}
     
    for (j=0;j<16 ;j++ )
                 if(in2 == seize[j])
                {
                return i+j-1;
                }
     
    return -1;
    }
    On peut utiiser aussi :
    char seize2[] = "0123456789ABCDEF";
    Petit Malin
    "accélérateur . . . qui pousse . . . un électron a passer par deux trous d’un écran en même temps." (Cyrille Burt: "C’est mieux qu’un fantôme") (Janus p.251)
    "Joy is to love what is, pain is to love what is not"
    )

    HP Pavilion Elite Desktop PC 570-p0xx - Window10 64 bits - Intel(R) Core(TM)2 Quad CPU Q8200 @ 3GHz x86_64-w64-mingw32-gcc-7.3.0.exe

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Funnyz Voir le message
    Merci pour ton post, on ma proposer cette solution de passé par les ascii pour récupérer le hex au final. s'il faut je peux recommencer mais je devrais avoir le résultat final comme http://www.string-functions.com/hex-string.aspx
    donc une char var[] = "646576656c6f7070657a2e6e6574"; qui dois me retourner en printf("valeur: %s - fin\n", hex); // écrit valeur: developpez.net - fin

    je débutes vraiment et j'ai pas vraiment compris ton calcule, je dois modifier quel partie du code ?
    Car j'ai fait plusieurs méthode pour arriver a un résultat et j'ai tjs eu des problèmes avec des lettres entre a-z alors que sa devrais gérer tout les caractères possible de la même manière que char mot[] = "\x..\x..";
    OK. Chaque groupe de 2 caractères hexa correspond à un caractère ASCII.

    Il suffit d'extraire des sous chaines 2 à 2 et de convertir la valeur. (avec affichage de contrôle) :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main (void)
    {
       char var[] = "646576656c6f7070657a2e6e6574";
     
       /* debut de la chaine */
       char *p = var;
     
       while (*p != 0)
       {
          /* extraire la sous-chaine de 2 caracteres */
          char s[3];
          *s = 0;
          strncat (s, p, 2);
     
          /* convertir en numerique (valeur numerique du caractere) */
          {
             int c = strtol (s, NULL, 16);
     
             /* affichage de controle */
             putchar (c);
          }
     
          /* on saute les 2 caracteres traites */
          p += 2;
       }
     
       /* terminer proprement l'affichage de controle */
       putchar ('\n');
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    developpez.net
     
    Process returned 0 (0x0)   execution time : 0.056 s
    Press any key to continue.
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    OK. Chaque groupe de 2 caractères hexa correspond à un caractère ASCII.

    Il suffit d'extraire des sous chaines 2 à 2 et de convertir la valeur. (avec affichage de contrôle) :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main (void)
    {
       char var[] = "646576656c6f7070657a2e6e6574";
     
       /* debut de la chaine */
       char *p = var;
     
       while (*p != 0)
       {
          /* extraire la sous-chaine de 2 caracteres */
          char s[3];
          *s = 0;
          strncat (s, p, 2);
     
          /* convertir en numerique (valeur numerique du caractere) */
          {
             int c = strtol (s, NULL, 16);
     
             /* affichage de controle */
             putchar (c);
          }
     
          /* on saute les 2 caracteres traites */
          p += 2;
       }
     
       /* terminer proprement l'affichage de controle */
       putchar ('\n');
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    developpez.net
     
    Process returned 0 (0x0)   execution time : 0.056 s
    Press any key to continue.
    j'aime bien mais on peut éviter la copie:
    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
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
     
    int main(void)
    {
       char var[] = "646576656c6f7070657a2e6e6574";
       assert(strlen(var) % 2 == 0); 
     
       for(char *p = var; *p != 0; p += 2)
       {
          int c;
     
          if(sscanf(p, "%2x", &c) == 1)
          {
             putchar(c);
          }
       }  
     
       putchar('\n');/* terminer proprement l'affichage de controle */
     
       return 0;
    }
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  7. #7
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Points : 169
    Points
    169
    Par défaut
    Je vais soulever des problèmes de l'ordre du dysfonctionnement du à l'utilisation humaine de ton programme.

    Comme dirait un de mes anciens profs :
    "La secrétaire blonde devant son pc, faut penser à ce qu'elle va taper !"

    Attention cependant à traiter ta chaine de caractères dans le bon "ordre".

    En effet comme tout le monde t'a dit un "caractère" est un COUPLE (donc 2 si je ne me trompe pas) de ce que tu vas présenté en entrée.

    Donc il risque d'y avoir un problème si :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char chaineSANSProbleme="0123456789";
    char chaineAVECProbleme="123456789";
    En effet dans le second cas tu va "taper" dans le vide (ou sur le '/0', 0, NULL).

    !!!Ceci est donc le premier point, faire attention au nombre de caractères hexadécimaux sur la ligne d'entrée.


    Deuxièmement, prend la précaution de placer des protection pour contrôler les caractères hexa arrivant sur la ligne d'entrée.

    Un petit 'Z' et tout foire.


    Finalement, certains OS risquent de mal interpréter tes "caractères" imprimables sur 2 octets, à cause du charset utilisé.



    Voilou, j'espère n'avoir pas dit trop de "co--eries".

    Bonne prog !

    Rilou

  8. #8
    Membre régulier Avatar de J4e8a16n
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 271
    Points : 119
    Points
    119
    Par défaut
    Citation Envoyé par J4e8a16n Voir le message
    Mon 4 sous:
    Ma fonction prends en paramètre 2 caractères qui viennent d'une source html
    <BODY>
    =1F=20=00Un grand =FA classique du Html (2.0 ?) m=EAme si cette balise META n'est que rarement utilis=E9 et alimente
    les trucs et astuces depuis des ann=E9es. Cette balise META charge automatiquement la page
    sp=E9cifi=E9e =E0l'attribut URL apr=E8s un d=E9lai de x secondes. Cé =E7=E2 l=40.
    </BODY>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int hx2car (char in, char in2)
    {
    int i, j;
    char seize[] = "0123456789abcdef";
     
    for (i=0;i<16 ;i++){
                 if(in == seize[i]){ i<<= 4;}
                 if(in2 == seize[i]){j = i -1;}
    }
    return i+j;
    }
    Y a plus simple

    TimeThis : Elapsed Time : 00:00:00.106(1/1000)
    Petit Malin
    "accélérateur . . . qui pousse . . . un électron a passer par deux trous d’un écran en même temps." (Cyrille Burt: "C’est mieux qu’un fantôme") (Janus p.251)
    "Joy is to love what is, pain is to love what is not"
    )

    HP Pavilion Elite Desktop PC 570-p0xx - Window10 64 bits - Intel(R) Core(TM)2 Quad CPU Q8200 @ 3GHz x86_64-w64-mingw32-gcc-7.3.0.exe

  9. #9
    Membre régulier Avatar de J4e8a16n
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 271
    Points : 119
    Points
    119
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int hx2car (char in, char in2)
    {
    char xx[3] = {0};
    xx[0] = in;
    xx[1] = in2;
    xx[2] =  '\0';
    return strtol (xx, NULL, 16);
    }
    Petit Malin
    "accélérateur . . . qui pousse . . . un électron a passer par deux trous d’un écran en même temps." (Cyrille Burt: "C’est mieux qu’un fantôme") (Janus p.251)
    "Joy is to love what is, pain is to love what is not"
    )

    HP Pavilion Elite Desktop PC 570-p0xx - Window10 64 bits - Intel(R) Core(TM)2 Quad CPU Q8200 @ 3GHz x86_64-w64-mingw32-gcc-7.3.0.exe

  10. #10
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par J4e8a16n
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int hx2car (char in, char in2)
    {
    int i, j;
    char seize[] = "0123456789abcdef";
     
    for (i=0;i<16 ;i++){
                 if(in == seize[i]){ i<<= 4;}
                 if(in2 == seize[i]){j = i -1;}
    }
    return i+j;
    }
    Y a plus simple
    Plus je ne sais pas, mais plus correct, sans aucun doute. En effet en exécutant ta fonction j'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    '0' '1' ==> 0x10
    '1' '1' ==> 0x15
    '0' 'Z' ==> 0x14
    Plusieurs raisons à ces erreurs :
    • La variable i sert à la fois d'index de boucle et de résultat de conversion, sachant que la modification dut à un de ses usages va avoir une répercussion négative dans l'autre usage.
    • La variable j n'est pas toujours initialisée.
    • Il n'y a pas de contrôle du format d'entrée.

Discussions similaires

  1. Conversion Hex en String
    Par Palsajicoco dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 06/09/2011, 14h18
  2. fonction "hex to string"
    Par philnext dans le forum Langage
    Réponses: 2
    Dernier message: 05/12/2010, 19h25
  3. convertion hex vers string
    Par mmarcoboss dans le forum Débuter
    Réponses: 5
    Dernier message: 11/01/2008, 08h03
  4. Convertion HEX en String
    Par zejo63 dans le forum Entrée/Sortie
    Réponses: 13
    Dernier message: 05/07/2007, 23h54
  5. string > hex
    Par AntoineNSG dans le forum C++
    Réponses: 8
    Dernier message: 28/02/2006, 13h44

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