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 (simple) cryptage XOR


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut Programme (simple) cryptage XOR
    Bonjour à tous,

    J'ai un petit soucis car je n'ai encore jamais manipulé les chaînes de caractères, et les opérateurs bit à bit. Il faudrait donc que je fasse un programme qui me code une chaine de caractère avec le caractère ASCII d'ordre 199 (sur tous les caractères de mon texte).

    J'ai testé plusieurs choses, mais voici ma dernière version :

    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
     
    #include <stdio.h>
    #include <string.h>
     
    char* CrypteDecrypte(char* MonTexte)
    {
        int i;
        for(i=0;i<strlen(MonTexte);i++)
        {
            MonTexte[i]=(char)MonTexte[i]^'199';
        }
        return MonTexte;
    }
     
     
    void AfficherCrypt(char* Texte)
    {
        int i;
        for(i=0;i<strlen(Texte);i++)
        {
            printf("%c", Texte[i]);
        }
    }
    int main() {
        char* Texte="o"; //test avec la lettre o minuscule
        CrypteDecrypte(Texte);
        AfficherCrypt(Texte);
        return 0;
    Donc dans ma fonction, j'ai tenté de caster le MonTexte[i] afin qu'il soit du même type que '199', mais un message apparait et dit "Multi-character character constant".
    Après, comme je vous l'ai dit, je ne sais pas si j'utilise la bonne méthode pour accéder à tous les éléments de ma chaine de caractères, car je n'ai encore jamais travaillé sur ce genre de chose.
    De plus, dans l'énoncé, il est écrit que le corps de la fonction peut être fait en une seule ligne. Or là j'en ai plusieurs car j'utilise une boucle. Mais je ne sais pas ce qu'ils veulent dire par "corps", peut-être seulement l'instruction de changer chaque caractère avec un XOR ?

    Merci d'avance pour votre réponse.

  2. #2
    Expert confirmé

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

    Erreur très classique : dans une chaine, les indices vont de 0 à strlen-1.

    D'autre part, attention : utiliser XOR peut conduire à remplacer un caractère valide par un 0 (zéro), ce qui posera un problème lorsque tu voudras décoder, le système voyant désormais une chaine de longueur inférieure à celle d'origine.
    Si les cons volaient, il ferait nuit à midi.

  3. #3
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Oui effectivement, je m'étais posé la question, et puis comme je n'avais pas vu d'erreurs, j'avais finalement laissé de 1 à strlen.

    Par exemple si on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        1011 1111
    XOR 1111 1111
    on obtient : 0100 0000 et je vais perdre le zéro le plus à gauche, soit 100 0000 ?

    Mais du coup, est-ce qu'il faut faire une boucle "pour" si je veux accéder à chaque caractère de ma chaine ? Et comment puis-je corriger ma ligne qui pose problème : Texte[i]=(char)Texte[i]^'199'; ?

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 38
    Points : 79
    Points
    79
    Par défaut
    Bon sur téléphone je ne peux pas éditer de message sans le supprimer.

    Utilise 199 au lieu de '199' car ce dernier est un nombre de 3 octets dont la représentation ASCII correspond au 3 caractères '1', '9' et '9'.

    Le problème du XOR n'est pas le 0 initial mais quand le résultat du XOR vaut 0. Cela correspond à un caractère de fin de chaîne. Donc ta chaîne cryptée paraitra avoir moins de caractère que ta chaîne d'origine.

  5. #5
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut
    J'ai changé ma ligne et j'ai mis Texte[i]=(char)Texte[i]^199; . J'ai aussi essayé avec Texte[i]=(int)Texte[i]^199; mais les deux ne marchent pas. Enfin, je ne sais pas si c'est une bonne chose de forcer le type comme je tente de faire.

  6. #6
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 562
    Points : 7 628
    Points
    7 628
    Par défaut
    Citation Envoyé par Stéphanois57 Voir le message
    J'ai changé ma ligne et j'ai mis Texte[i]=(char)Texte[i]^199; . J'ai aussi essayé avec Texte[i]=(int)Texte[i]^199; mais les deux ne marchent pas. Enfin, je ne sais pas si c'est une bonne chose de forcer le type comme je tente de faire.
    Qu'est-ce qui te fait dire que cela ne marche pas?
    Les deux cast que tu fais sont inutiles, mais la fonction crypte bien avec le caractère de code ASCII 199.
    Attention, comme il te l'a été dis, les caractères cryptés risquent de ne plus être affichables, et en particulier ne pas tenter de crypter le caractère de code 199 car celui-ci se transformerait en terminateur.
    En une ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(size_t i=0;i<strlen(MonTexte);i++) MonTexte[i] ^= (char)199;

  7. #7
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut
    Qu'est-ce qui te fait dire que cela ne marche pas?
    --> J'ai ma ligne qui devient rouge et il est écrit : Thread 1 : EXC_BAD ACCESS (code=2, address=0x100000f9b). Je suis sur Xcode je précise.

    J'ai tenté comme tu m'as dis, mais j'ai exactement le même message qui apparaît.
    Juste une petite précision : à quoi sert le size_t ?

    On ne peut tout simplement PAS coder le caractère 199 avec un XOR 199, ou il existe une manière de contourner le problème ?

  8. #8
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Bonjour,
    je vois que tu patauges grave.
    Un bad access doit être l'équivalent d'un segfault sur les autres architectures ; c'est une supposition que je ne'ai pas vérifiée. Cela signifierait que tu accèdes à de la mémoire qui ne t'appartient pas.

    size_t est le type d'entier qui est utilisé en C moderne pour contenir des taille d'objet, c'est le type de l'entier renvoyé par strlen ou sizeof par exemple.

    Chiffrer (et non crypter) par xor est simple : tu interprètes ta chaîne comme une suite de bytes et tu effectues un xor dessus. C'est une opération symétrique → chiffre = déchiffrer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    char *xorify( const char *string, int xor_key)
    {
      size_t len=strlen(string);
      char *res=malloc(len+1);
      if (res!=NULL) {
        for(size_t i=0; i<len; ++i)
          res[i] = string[i] ^ xor_key;
        res[len]=0;
      }
      return res;
    }
    Ici cette fonction alloue de la mémoire pour une nouvelle chaîne, on boucle sur les caractères de de string en leur appliquant le xor. On finit avec le rajout du marqueur de fin de chaîne et voilà.

    Elle s'utilisera comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int main(void)
    {
      int key=199;
      char *message[]="hello world";
      char *encrypted=xorify(message,key);
      char *decrypted=xorify(encrypted,key);
      puts(message);
      puts(decrypted);
     
      free(decrypted);
      free(encrypted);
     
      return 0;
    }
    Si tu veux «voir» le message chiffré alors affiche le non en caractère mais en nombre →
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void hex_display(const char *string)
    {
      for(size_t i=0; i<strlen(string); ++i)
        printf(" %02x", string[i]);
      putchar('\n');
    }
    Code tapé à la volée non testé.

  9. #9
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Merci pour ta réponse.
    Je vais regarder en détails ce que tu m'as écrit, car j'avoue être un peu perdu là.
    Mais ça me parait un peu bizarre, il n'y a pas moyen de faire beaucoup plus simple ? Car nous n'avons jamais vu le type chaine de caractère, cet exercice avait l'air plutôt de s'apparenter à une "introduction"...

  10. #10
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut
    J'ai analysé ce que tu as fait, mais j'ai des questions, car je ne comprends pas tout.
    Tout d'abord, concernant le résultat que ça m'affiche. J'ai fait "o" XOR 199.
    Logiquement, on devrait trouver :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      0000 0111     //Code binaire du o minuscule
    ^ 1100 0111    // Code binaire du caractère ASCII 199
    = 1100 0000
    = 192 en décimal
    Or le programme m'affiche ffffffa8. Ça ne correspond pas ça ??

    Ensuite, je vais te mettre en commentaires directement à côté des lignes, ça sera plus simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    char *xorify( const char *string, int xor_key)
    {
      size_t len=strlen(string);
      char *res=malloc(len+1); // Pourquoi on alloue une zone mémoire de len+1. En fait, c'est le +1 que je ne comprends pas
      if (res!=NULL) { // Res vaudra NULL une fois la boucle for terminée ?
        for(size_t i=0; i<len; ++i)
          res[i] = string[i] ^ xor_key;
        res[len]=0; // Pour sortir du if du coup ?
      }
      return res;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void hex_display(const char *string)
    {
      for(size_t i=0; i<strlen(string); ++i)
        printf(" %02x", string[i]); // Ca correspond à quoi le 02x ?
      putchar('\n');
    }

  11. #11
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    En ascii le o minuscule 'o' a pour code 111 en décimal soit 0x6F ou 0b0110 1111.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    'o' 111 : 0110 1111
        119 : 0111 0111
              0001 1000 -> 24 en décimal ou 0x18
    Dans le code xorify :

    ligne 5: une chaîne de caractère doit toujours se terminer par un zéro terminal (il porte bien son nom). Donc une chaîne comme "YO" est en fait un tableau de 3 caractères 'Y' 'O' '\0'.

    ligne 6: il faut toujours tester le retour des allocations mémoires car elles peuvent échouer. Par exemple si malloc n'a pas réussi à allouer une zone mémoire de la taille demandé il renvoie le pointeur NULL. Soit tu stoppes ton programme en affichant un message d'erreur, ou tu ne fais rien en te disant que c'est celui qui va appeler ta fonction qui va s'occuper du problème. Ici j'ai choisi la deuxième option : la fonction xorify renvoie soit une chaîne correctement allouée soit NULL.

    ligne 9: non pour terminer correctement la chaîne de caractère que je crée : elle doit se terminer par un 0 terminal.

    Dans le code de hex_display : c'est pour le formatage à l'écran. J'aurais dû préciser qu'il s'agit d'afficher des bytes …

    J'aurais également dû suivre le conseil avisé de SunWuKong.

    Un code plus correct donne :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    char *xorify(size_t size, const char *string, int xor_key)
    {
      char *res=malloc(size+1);
      if (res!=NULL) {
        for(size_t i=0; i<size; ++i)
          res[i] = string[i] ^ xor_key;
        res[size]=0;
      }
      return res;
    }
     
    void decimal_display(size_t size, const char *string)
    {
      for(size_t i=0; i<size; ++i)
        printf(" %03hhu", (unsigned char)string[i]); 
      putchar('\n');
    }
     
    int main(void)
    {
      int key=119;
      const char message[]="hello world";
      size_t size=strlen(message);
     
      char *encrypted=xorify(size, message,key);
      char *decrypted=xorify(size, encrypted,key);
     
      puts(message);
     
      decimal_display(size, message);
      decimal_display(size, encrypted);
     
      puts(decrypted);
     
      free(decrypted);
      free(encrypted);
     
      return 0;
    }

  12. #12
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Merci pour toutes ces explications. Je comprends tout ce que tu as fait, mais je n'aurais pas eu le réflexe d'aller mettre des malloc ou toutes ces choses là, vu que je ne connaissais encore pas tellement les chaines de caractères.
    Juste quelques précisions :
    -le %03hhu, il correspond "vaguement" au %d ou au %c ou à aucun ? Comment peut-on connaitre tous ces "codes" ?
    - puts et putchar c'est la même chose ? Sont-ils équivalents à printf ?
    - Les free qu'on fait à la fin, c'est pour libérer la mémoire allouée par decrypted et encrypted ? Si c'est le cas, c'est primordial de le faire dans ce programme simple ? (je parle bien de cet unique programme)

  13. #13
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Citation Envoyé par Stéphanois57 Voir le message
    -le %03hhu, il correspond "vaguement" au %d ou au %c ou à aucun ? Comment peut-on connaitre tous ces "codes" ?
    0→ compléter à gauche l'écriture du nombre par des 0
    3→ écrire le nombre sur 3 positions minimum
    hh → interpréter l'argument comme un char
    u→interpréter l'argument comme un entier non signé

    Pour tous renseignements sur les directives printf il suffit de faire un man 3 printf ou une recherche google ou pour les plus courageux consulter la norme C11 «7.21.6.1 The fprintf function» p327.

    Citation Envoyé par Stéphanois57 Voir le message
    - puts et putchar c'est la même chose ? Sont-ils équivalents à printf ?
    puts = PUT String → affiche un char * sur stdout
    putchar = PUT CHAR → affiche un unique char sur stdout
    idem → man puts, man putchar, google, norme.

    Citation Envoyé par Stéphanois57 Voir le message
    - Les free qu'on fait à la fin, c'est pour libérer la mémoire allouée par decrypted et encrypted ? Si c'est le cas, c'est primordial de le faire dans ce programme simple ? (je parle bien de cet unique programme)
    Il est toujours plus propre de libérer tout ce que tu as alloué. C'est une bonne pratique de le faire TOUJOURS. Un bon réflexe qui t'évitera de mauvaises surprises.
    Néanmoins, il y a des cas où c'est mieux de ne pas le faire. Si tu as alloué énormément de mémoire, le fait de libérer à la fin de ton programme ce qui est encore alloué peut prendre du temps, d'autant plus que cette libération est «automatiquement faite par l'OS» (pour les OS modernes). Donc ne pas faire de free tout à la fin permet de finir le programme plus rapidement. Mais bon, cette «excuse» n'est valable que pour les très gros programmes. L'effet le plus malicieux est que ces pratiques font qu'ils donnent souvent de faux positifs dans les outils de détection de fuite mémoire, ce qui ne rend pas le débogage plus facile.

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Stéphanois57 Voir le message
    -le %03hhu, il correspond "vaguement" au %d ou au %c ou à aucun ? Comment peut-on connaitre tous ces "codes" ?
    En lisant la doc de printf. Pour être précis, 3 c'est la longueur minimale, 0 (Edit: WTF? Il devrait y avoir un zéro là-dedans) c'est pour préfixer avec des zéros plutôt que des espaces, hh signifie que la valeur qu'on passe est de taille char, et u c'est comme d, mais pour des valeurs unsigned.

    - puts et putchar c'est la même chose ? Sont-ils équivalents à printf ?
    puts() écrit une chaîne sans formatage (contrairement à printf()) et ajoute automatiquement une fin de ligne à la suite.
    putchar() écrit un seul caractère.

    - Les free qu'on fait à la fin, c'est pour libérer la mémoire allouée par decrypted et encrypted ? Si c'est le cas, c'est primordial de le faire dans ce programme simple ? (je parle bien de cet unique programme)
    Ne pas le faire n'est pas portable: Même si sous Windows ou Linux, l'OS nettoie derrière toi, sur certaines plate-formes, ça pourrait être une fuite de mémoire.

    *À noter que tandis que h existe en C depuis le standard C90, hh nécessite le standard C99 et par conséquent, n'est pas pris en compte par Micro$oft Visual C++. Ce n'est pas dangereux dans printf(), mais c'est extrêmement dangereux dans scanf().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Je vous remercie pour toutes ces explications ! Au moins, j'aurai appris des choses...

    Une dernière question : quand je crypte la chaine "o" ça me sort 168. Normal. Mais quand je crypte 168, ça ne me donne pas o. Je crois que c'est normal, car d'après mon programme, ça va convertir en binaire chaque chiffre de 168 et faire un Xor 199 avec chacun de ceux-ci. Cependant, y a-t-il possibilité de faire en sorte qu'en cryptant 168 ça me sorte o ?

  16. #16
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Tu ne donnes pas de code donc j'imagine simplement que tu ne sais pas encore qu'un print ne fait qu'afficher une donnée de la manière dont tu le demandes. Si tu utilises un %c tu vas lui demander d'afficher le caractère de code dont tu donnes la valeur, avec un %d tu lui demandes d'afficher un nombre dont tu donnes la valeur.

    Exemple pour comprendre :
    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
    #include <stdio.h>
     
    int main(void)
    {
      char o='o';
      char n=168^199;
     
      printf("En utilisant %%c :\n"
             "\to = %c\n"
             "\tn = %c\n", o,n);
     
      printf("En utilisant %%hhu :\n"
             "\to = %hhu\n"
             "\tn = %hhu\n", o,n);
     
      return 0;
    }

  17. #17
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut
    Non, ça je comprends.
    Je m'explique : pour 168 (qui correspond à mon "o" crypté par le programme)
    Mon programme va d'abord séparer le 168 en "1", "6", "8". Ce qui donne respectivement en équivalence décimale : 49, 54, 56.
    Ensuite il code ça en binaire : 00110001 , 00110110 , 00111000.
    Ensuite il fait un XOR avec le caractère décimal 199, soit en décimal : 11000111.
    Ce qui donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    00110001  00110110  00111000
    11000111  11000111  11000111
     
    11111110  11110001  11111111
     
    254       241           255             en décimal
    D'ailleurs je ne sais pas pourquoi mais le programme m'affiche 246 241 255 et non pas 254 241 255.

    Ma question était de savoir, si, en entrant 168 comme texte à coder, il pouvait me ressortir la chaine "o" ? Il me semble qu'il faut faire un programme différent du coup, ce n'est pas juste une question d'affichage, car une chaine ayant 246 241 255 comme code décimal, afficherait des symboles bizarres, et non pas "o".

  18. #18
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Déjà, tu t'es gouré sur le premier nombre, il devrait avoir un bit de plus à zéro:
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    00110001
    11000111
        ^
    Ensuite, cela ne devrait pas arriver, car dans le code que tu as posté je ne vois rien qui convertisse les caractères de la chaîne en représentations décimales de leur code.

    Edit: Pour finir, si tu veux éviter d'afficher les caractères "bizarres", peut-être peux-tu les représenter par des séquences d'échappement (celles utilisées dans les adresses Web, %+code hexa, me paraissent appropriées)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  19. #19
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2015
    Messages
    224
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2015
    Messages : 224
    Points : 62
    Points
    62
    Par défaut
    Excuse-moi, mais je ne trouve pas mon erreur... Tu parles du 49 ? 49 c'est la représentation décimale du 1 dans la table ASCII. Ce qui donne bien en binaire : 00110001 ?

    Mon affichage décimal s'est fait sur la base de celui suggéré par picodev, soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void decimal_display(size_t size, const char *string)
    {
      for(size_t i=0; i<size; ++i)
        printf(" %03hhu", (unsigned char)string[i]); 
      putchar('\n');
    }
    Ce n'est pas cela dont tu parles ?

  20. #20
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Peux-tu poster ton code complet?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Quel langage de programmation pour des programmes simples ?
    Par Pierre.g dans le forum Langages de programmation
    Réponses: 18
    Dernier message: 22/11/2006, 15h22
  2. Programme "simple" devient très lent ?
    Par Invité dans le forum Delphi
    Réponses: 8
    Dernier message: 18/09/2006, 23h32
  3. Création de programme simple
    Par mz-hacker dans le forum Windows
    Réponses: 1
    Dernier message: 06/08/2006, 01h34
  4. programme de cryptage
    Par hamadibensassi dans le forum C
    Réponses: 14
    Dernier message: 01/06/2006, 21h30
  5. [delphi 7 perso] Cryptage XOR et assembleur
    Par Loran dans le forum Langage
    Réponses: 5
    Dernier message: 18/08/2005, 11h44

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