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 :

Chiffrage de fichier avec XOR


Sujet :

C++

  1. #21
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void crypt(char *text, int length, mpz_class key, char *crypted) {
    [...]
     
             // Lis la clé en boucle
             if (i%keychar.length() == 0) { // <-- ICI je ne devrais pas utiliser length ???
    Je ne sais pas ce qu'est keychar . Mais globalement, je verrais plutôt crypt de cette cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void crypt(char *text, int text_length, unsigned char* key, unsigned int key_length, char *crypted)
    Et là tu utilises key_length.

    Sinon, ton code m'a l'air bon. S'il te reste des problèmes, il se peut qu'ils soient au niveau de l'écriture du fichier (tu dois l'écrire en binaire et pas en ascii).

    Ah, pour la clé :

    Merci bien ! Je ne connaissais pas. Il y a moyen d'utiliser cette définition avec une clé entrée au clavier avec getline() ?
    Non, il n'y a pas. Si tu fais saisir la clé au clavier, il faut la mettre dans un std::string, et ensuite, convertir cette forme chaîne sous la forme tableau de char* (c'est un nom catastrophique char*, ici, en fait, on utilise char car sizeof(char) == 1, mais c'est bien en tant qu'octet/valeur de 0 à 255 qu'on les traite).

    Pour la conversion, le plus simple est de lire 2 caractères dans ta chaîne, et de les convertir en entier (en faisant attention à bien préciser que c'est de l'hexadécimal), et ainsi de suite jusqu'à avoir consommé toute la chaîne.

  2. #22
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Par défaut
    merci de ton aide white_tentacle, je vais me concentrer sur le reste du code dès que j'arrive cette histoire de conversion de clé. J'ai essayer pleins de méthode et je commence à plus rien y voir

    J'ai quand même décidé de séparer pour bien clarifier mon code. J'en suis ici :

    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
    #include <cstdlib>
    #include <iostream>
     
    using namespace std;
     
    char checksum2bin(char *hexkey, int length) {
         char result[length];
         for (int i=0; i*2<length; i++) {
             int tmp[2];
             for (int j=0; j<2; j++) {
                 char car = hexkey[i*2+j];
                 int conv;
                 switch (car) {
                        case '0': conv = 0x0; break;
                        case '1': conv = 0x1; break;
                        case '2': conv = 0x2; break;
                        case '3': conv = 0x3; break;
                        case '4': conv = 0x4; break;
                        case '5': conv = 0x5; break;
                        case '6': conv = 0x6; break;
                        case '7': conv = 0x7; break;
                        case '8': conv = 0x8; break;
                        case '9': conv = 0x9; break;
                        case 'a': conv = 0xa; break;
                        case 'b': conv = 0xb; break;
                        case 'c': conv = 0xc; break;
                        case 'd': conv = 0xd; break;
                        case 'e': conv = 0xe; break;
                        case 'f': conv = 0xf; break;
                        default: cout << "Error"; return -1;
                 }
                 cout << i << "," << j << ": " << conv << endl;
                 tmp[j] = conv;
             }
             // 1 byte
             char chartmp[1];
             // Les deux 4 bits affichés en hexa
             // sont correctes !
             _itoa(tmp[0], chartmp, 16);
             cout << "\tR:" << chartmp << endl;
             _itoa(tmp[1], chartmp, 16);
             cout << "\tR:" << chartmp << endl;
     
             // Combinaison de deux 4 bits ensemble
             // 0101 1001 => 01011001
             // Comment faire ???
             result[i] = tmp[0] + tmp[1];
         }
         return *result;
    }
     
    int main(int argc, char *argv[])
    {    
        char *key = "9cdfb439c7876e703e307864c9167a15";
        cout << "Final" << checksum2bin(key, 32) << endl;
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    J'ai commenté où j'ai un problème: pour combiner les 4 bits ensemble pour faire 8 bits donc 1 byte. Je ne sais pas comment les "attacher" dans le même octet, quelle opération utilisé (à la place du "+" bien sûr).

    Voici ce que sort le programme si jamais :
    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
    /*
    0,0: 9
    0,1: 12
            R:9
            R:c
    1,0: 13
    1,1: 15
            R:d
            R:f
    2,0: 11
    2,1: 4
            R:b
            R:4
    3,0: 3
    3,1: 9
            R:3
            R:9
    4,0: 12
    4,1: 7
            R:c
            R:7
    5,0: 8
    5,1: 7
            R:8
            R:7
    6,0: 6
    6,1: 14
            R:6
            R:e
    7,0: 7
    7,1: 0
            R:7
            R:0
    8,0: 3
    8,1: 14
            R:3
            R:e
    9,0: 3
    9,1: 0
            R:3
            R:0
    10,0: 7
    10,1: 8
            R:7
            R:8
    11,0: 6
    11,1: 4
            R:6
            R:4
    12,0: 12
    12,1: 9
            R:c
            R:9
    13,0: 1
    13,1: 6
            R:1
            R:6
    14,0: 7
    14,1: 10
            R:7
            R:a
    15,0: 1
    15,1: 5
            R:1
            R:5
    Final§
    */

  3. #23
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Quelques petites remarques :
    • Tu renvoies un buffer alloué localement (char result[length] ). C'est très mal, puisque ce buffer n'existera plus lorsque tu seras sorti de la fonction. Il faut donc que tu prennes le buffer en paramètre, et qu'il soit alloué dans l'appelant. Et tant qu'à faire, autant utiliser un std::vector<char> qui t'évitera bien des problèmes (d'ailleurs, tu as de la chance que ça compile, car en C++, tu ne peux pas définir un tableau avec une taille passée comme paramètre de ta fonction, du moins, pas pour l'instant).
    • Tu alloues un buffer de taille 32 pour result, mais il va en réalité faire 16 caractères seulement
    • Si length est impaire, ton code fait un buffer overflow (certes, tu ne peux pas interpréter la chaîne correctement, mais il ne faut pas faire de dépassement de tableau pour autant)

    Pour combiner tes deux quartets ensemble, il te suffit d'utiliser le décalage de bits au moyen de l'opérateur << et l'addition, donc ça donnerait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result[i] = (tmp[0] << 4) + tmp[1];
    Par contre, tu ne peux pas afficher le résultat au moyen d'un cout simple, en effet, il peut contenir plein de caractères non imprimables. Utilise plutôt, pour l'afficher :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(int i = 0; i < buffer.size(); ++i) 
       std::cout << std::hex << std::setw(2) << std::setfill('0') << (int) buffer[i];
    en ayant bien inclus l'en-tête <iomanip> .

    Bon courage !

  4. #24
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Par défaut
    Super j'obtient la convertion correctement ! Par contre il y a un petit soucis, lors de l'affichage certaines valeurs sont en ffffffxx d'autres 000000xx (xx étant correcte). Enfin mieux vaut que je vous montre la sortie :

    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
    /*
    ffffff9c
    ffffffdf
    ffffffb4
    00000039
    ffffffc7
    ffffff87
    0000006e
    00000070
    0000003e
    00000030
    00000078
    00000064
    ffffffc9
    00000016
    0000007a
    00000015
    */
    Et le code, j'ai suivit tout tes conseils. Concernant length je controle (dans l'autre code) si la longueur de la clé est puissance de 2 donc il n'y aura aucun problème dans le code final. J'ai utilisé les vector qui sont finalement très simples à utiliser ! L'adaptation du code fut très rapide en plus.

    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
    #include <cstdlib>
    #include <iostream>
    #include <iomanip>
    #include <vector>
     
    using namespace std;
     
    void checksum2bin(char *hexkey, int length, vector<char> &result) {
         for (int i=0; i*2<length; i++) {
             int tmp[2];
             for (int j=0; j<2; j++) {
                 char car = hexkey[i*2+j];
                 int conv;
                 switch (car) {
                        case '0': conv = 0x0; break;
                        case '1': conv = 0x1; break;
                        case '2': conv = 0x2; break;
                        case '3': conv = 0x3; break;
                        case '4': conv = 0x4; break;
                        case '5': conv = 0x5; break;
                        case '6': conv = 0x6; break;
                        case '7': conv = 0x7; break;
                        case '8': conv = 0x8; break;
                        case '9': conv = 0x9; break;
                        case 'a': conv = 0xa; break;
                        case 'b': conv = 0xb; break;
                        case 'c': conv = 0xc; break;
                        case 'd': conv = 0xd; break;
                        case 'e': conv = 0xe; break;
                        case 'f': conv = 0xf; break;
                        default: cout << "Error"; return;
                 }
                 tmp[j] = conv;
             }
             // Combinaison de deux 4 bits ensemble
             result[i] = (tmp[0] << 4) + tmp[1];
         }
         return;
    }
     
    int main(int argc, char *argv[])
    {    
        char *key = "9cdfb439c7876e703e307864c9167a15";
        vector<char> keyArray(16);
        checksum2bin(key, 32, keyArray);
        for(int i = 0; i < keyArray.size(); ++i) {
           cout << std::hex << setw(8) << setfill('0') << (int) keyArray[i] << endl;
        }
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    Vraiment je te remercie déjà beaucoup pour ton soutient, merci white_tentacle !

  5. #25
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 413
    Par défaut
    C'est un problème d'extension de signe. Tu dois passer par un unsigned char pour éviter cela.
    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.

  6. #26
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Par défaut
    Super, merci médinoc !

    J'ai contrôlé, chiffrage/déchiffrage se passe normalement. J'ai fais quelques opérations de xor à la main par-ci par-là et ça semble concorder. Je dirais que c'est terminé tout est bon !!! *ouf*
    Voici le code final:

    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
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    //#include <math.h>
    #include <vector>
    //#include <iomanip>
     
    using namespace std;
     
    // Chiffrage
    // -- selon une clé char
    // -- (non utilisée)
    void crypt(char *text, int length, char *key, char *crypted) {
         int j = 0;
         for (int i = 0; i < length; i++) {
             // Lis la clé en boucle
             if (i%strlen(key) == 0) {
                   j=0;
             }
             // XOR
             crypted[i] = text[i] ^ key[j];
             j++;
         }
    }
     
    // -- selon une clé en binaire
    void crypt(char *text, int length, vector<unsigned char> key, char *crypted) {
         int j = 0;
         for (int i = 0; i < length; i++) {
             // Lis la clé en boucle
             if (i%key.size() == 0) {
                   j=0;
             }
             // XOR
             crypted[i] = text[i] ^ key[j];
             j++;
         }
    }
     
    // Conversion de la clé char en vrai hex
    void checksum2bin(char *hexkey, int length, vector<unsigned char> &result) {
         for (int i=0; i*2<length; i++) {
             int tmp[2];
             for (int j=0; j<2; j++) {
                 char car = hexkey[i*2+j];
                 int conv;
                 switch (car) {
                        case '0': conv = 0x0; break;
                        case '1': conv = 0x1; break;
                        case '2': conv = 0x2; break;
                        case '3': conv = 0x3; break;
                        case '4': conv = 0x4; break;
                        case '5': conv = 0x5; break;
                        case '6': conv = 0x6; break;
                        case '7': conv = 0x7; break;
                        case '8': conv = 0x8; break;
                        case '9': conv = 0x9; break;
                        case 'a': conv = 0xa; break;
                        case 'b': conv = 0xb; break;
                        case 'c': conv = 0xc; break;
                        case 'd': conv = 0xd; break;
                        case 'e': conv = 0xe; break;
                        case 'f': conv = 0xf; break;
                        default: cout << "Error"; return;
                 }
                 tmp[j] = conv;
             }
             // Combinaison de deux 4 bits ensemble
             result[i] = (tmp[0] << 4) + tmp[1];
         }
         return;
    }
     
    int main(int argc, char *argv[])
    {
        // Prend en paramètre fichier src, fichier dst
        if (argc != 3) {
             cout << "Usage: " << argv[0] << " <fichier src> <fichier dst>" << endl;
             system("PAUSE");
             return 0;
        }
        else {
             cout << "Fichier d'entree: \t" << argv[1] << endl;
             cout << "Fichier en sortie: \t" << argv[2] << endl;
        }
        char *filename_in = argv[1];
        char *filename_out = argv[2];
     
        // Ouverture des fichiers
        fstream file_in(filename_in, ios::in|ios::binary);
        fstream file_out(filename_out, ios::out|ios::binary);
        if (!file_in || !file_out) {
              cout << "Impossible d'ouvrir !";
              system("PAUSE");
              return 0;
        }
     
        // Clé en char hex
        //char *key = "9cdfb439c7876e703e307864c9167a15";
        string keyString;
        cout << "Entrez la clef de chiffrage: ";
        getline(cin, keyString);
        char *key = (char *) keyString.c_str();
        int keylength = strlen(key);
        // Teste si la longueur est puissance de 2
        if ( ((keylength & -keylength) xor keylength) != 0 ) {
              cout << "La longueur de la cle doit etre une puissance de 2." << endl;
              system("PAUSE");
              return 0;
        }
     
        // Convertit la clé en binaire gros int (mpz_class)
        vector<unsigned char> keyArray(16);
        checksum2bin(key, keylength, keyArray);
     
        // Variable de lecture
        int iter = 0;
        const int tranche = 192;
        char buffer[tranche];
     
        // Determine la longueur du fichier
        file_in.seekg(0, ios::end);
        int file_inlength = file_in.tellg();
        file_in.seekg(0, ios::beg);
     
        // Lis par tranche de tranche octets
        while (iter*tranche < file_inlength) {
              // Octet actuel
              int readByte;
              readByte = tranche;
              // Faut-il reduire la tranche de read/write
              if (iter*tranche+tranche > file_inlength)
                 readByte = file_inlength-iter*tranche;
              strcpy(buffer, "");
              // Lis une tranche d'octets, chiffre et écrit
              file_in.read(buffer, readByte);
              char tmp[readByte];
              crypt(buffer, readByte, keyArray, tmp);
              file_out.write(tmp, readByte);
              iter++;
        }
     
        // Ferme les fichiers
        file_in.close();
        file_out.close();
     
        cout << "\nFini\n";
        system("PAUSE");
        return 0;
    }
    Si vous avez des commentaires, suggestions ou corrections à demander surtout n'hesitez pas !
    Je voulais remercier tous ceux qui m'ont aider, je n'aurais rien pu faire sans vous alors merci infiniment !

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. parser un fichier avec xerces
    Par traiangueul dans le forum XML/XSL et SOAP
    Réponses: 9
    Dernier message: 02/02/2004, 18h14
  2. Réponses: 8
    Dernier message: 14/11/2003, 22h51
  3. Dossier ou Fichier avec ShellListView
    Par MoussDiouf dans le forum Langage
    Réponses: 6
    Dernier message: 14/06/2003, 12h33
  4. [VB6] [Réseau] Récupérer la taille d'un fichier avec inet
    Par pcpunch dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 20/02/2003, 21h38
  5. enregistrer dans un fichier avec une appli mdi
    Par ferrari dans le forum C++Builder
    Réponses: 4
    Dernier message: 05/05/2002, 15h17

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