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 :

Problème sur codage XOR.


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 169
    Points : 60
    Points
    60
    Par défaut Problème sur codage XOR.
    Bonjour à tous.

    Ayant pour but de m’entraîner à manipuler du code C++, je suis tombé sur ceci :

    http://www.primenumbers.net/Renaud/fr/crypto/XOR.htm

    J'ai donc voulu essaye d'appliquer cette méthode de codage de texte sur un fichier, ce qui m'à mené à pondre ce petit programme dont voici le code :

    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
    #include <iostream>
    #include <fstream>
    #include <string>
     
    using namespace std;
     
    int main()
    {
    	ifstream file("fichier.txt" , ios::in|ios::binary);
    	string key = "nimp";
    	char texteOrigin, texteConv[10];
     
    	for (int i(0), j(0); i < 10;i++, j++)
    	{
     
    		file.read((char *)&texteOrigin, sizeof(char));
    		if (j > key.size())
    		{
    			j = 0;
    		}
     
    		texteConv[i] = texteOrigin ^ key[j];
    	}
     
    	file.close();
    	cout << texteConv << endl;
    	ofstream fileenc("fichier.txt", ios::out|ios::trunc);
    	fileenc << texteConv;
    	system("pause");
    	return 0;
    }
    J'aimerais avoir votre avis sur ce code, car je me retrouve avec un petit problème lors du décodage.

    à savoir : pour tester ce petit programme, j'ai créé un fichier nommé "fichier.txt".
    Ce fichier contient simplement cette ligne : "azertyuiop".

    Le codage ce passe bien (je pense).
    Mais le décodage... Aie :

    Je me retrouve bien avec mes 10 caractères "azertyuiop" en début de mon fichier "fichier.txt", mais ils sont suivit de caractères assez "bizarres", je ne sais pas si c'est pas les caractères résultant du codage précédent.

    En mode pas à pas, ma variable texteConv contient bien RIEN-QUE mes caractères "azertyuiop" lorsque je demande au programme de me l'enregistrer dans le fichier txt (ligne d'instruction N°28).

    donc je ne comprends pas trop ce qu'il ce passe.

    ps:
    Texte dans fichier.txt non codé : "azertyuiop"
    Texte dans fichier.txt codé : "tpÌÌÌÌÌÌÌÌÌÌÌÌÌpÌÌÌÌÌÌÌÌ"
    Texte dans fichier.txt décodé : "azertyuiopÌÌÌÌÌÌÌÌÌÌÌÌÌpÌÌÌÌÌÌÌÌà"2nimp"
    (sans les " aux extrémités).

    Merci !

  2. #2
    Membre émérite
    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
    Points : 2 799
    Points
    2 799
    Par défaut
    texteConv n’est pas terminé par un '\0'. Donc tu ne peux pas l’envoyer tel quel à travers un flux. Tu peux utiliser « write ».

    Plutôt que « read », tu peux utiliser « get » pour lire un caractère à la fois.

    Et sinon, plutôt que d’utiliser des char* ou des char[], utilise des std::vector<char> (ou std::array<char, 10>), cela t’évitera des erreurs. char* est à réserver pour les chaînes terminées par des '\0', quand utiliser std::string n’est pas possible.

  3. #3
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 169
    Points : 60
    Points
    60
    Par défaut
    Merci pour votre réponse.

    J'ai suivis vos conseils et ai modifié mon code.
    Il est à présent comme 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
     
    using namespace std;
     
    int main()
    {
    	ifstream file("fichier.txt" , ios::in|ios::binary);
    	string key = "nimp";
    	vector <char>  texteConv;
    	char texteOrigin;
     
    	for (int i(0), j(0); i < 10;i++, j++)
    	{
    		file.get(texteOrigin);
    		if (j > key.size())
    		{
    			j = 0;
    		}
     
    		texteConv.push_back(texteOrigin ^ key[j]);	
    		cout << texteConv[i];
    	}
     
    	cout << endl;
     
    	file.close();
     
    	ofstream fileenc("fichier.txt", ios::out|ios::trunc);
    	for (int i(0); i < texteConv.size(); i++)
    	{
    		fileenc.write(&texteConv[i],texteConv.size());
    	}
     
    	system("pause");
    	return 0;
    }
    à présent, dans mon fichier décodé je me retrouve avec ceci :

    "azertyuiopzertyuiopÍertyuiopÍÍrtyuiopÍÍÍtyuiopÍÍÍýyuiopÍÍÍýýuiopÍÍÍýýýiopÍÍÍýýýýopÍÍÍýýýýŸpÍÍÍýýýýŸó", au lieu de "azertyuiop" à l'origine.

    Bien que sur la console, mon résultat qui s'affiche est bien "azertyuiop"...

    Je pense que mon erreur viens de la dernière boucle for (ligne 32 à 35), j'ai pensé à le modifier comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (int i(0); i < texteConv.size(); i++)
    {
    	fileenc.write(&texteConv[i],i);
    }
    pour écrire caractère par caractère et non 10 fois 10 caractères (ce qui était illogique dans le code), mais ça ne fonctionne pas non plus...

    J'ai aussi essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (int i(0); i < texteConv.size(); i++)
    {
    	fileenc.put(texteConv[i]);
    }
    Mais c'est pas non plus approprié apparemment.

  4. #4
    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 519
    Points
    41 519
    Par défaut
    C'est pourtant bien la dernière solution qui est la bonne...
    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.

  5. #5
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    L'erreur vient de là : fileenc.write(&texteConv[i],texteConv.size());. D'un côté tu demandes d'écrire un caractère à la fois et de l'autre tu lui demandes d'écrire toutes les données d'un coup. Prends quelques minutes pour lire et comprendre la documentation de std::ostream::write() et celle de std::vector::data et tu sauras quoi écrire .
    -- Yankel Scialom

  6. #6
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 169
    Points : 60
    Points
    60
    Par défaut
    Citation Envoyé par prgasp77 Voir le message
    D'un côté tu demandes d'écrire un caractère à la fois et de l'autre tu lui demandes d'écrire toutes les données d'un coup.
    Voilà pourquoi j'ai fini par écrire : fileenc.write(&texteConv[i],i); (que j'ai écris dans le post précédent). Mais ça fonctionne toujours pas ! où alors quelque chose m'échappe !

  7. #7
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    RTFM !
    1. Que prend en second argument la méthode std::basic_ostream::write ?
    2. Qu'est i ?
    3. Est-ce la même chose ?
    -- Yankel Scialom

  8. #8
    Membre émérite
    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
    Points : 2 799
    Points
    2 799
    Par défaut
    Sinon, dans un premier temps, peut-être utiliser put() plutôt que write. C’est le symétrique de get().

    Dans un autre genre, la boucle devrait être réécrite pour ne pas lire 10 caractères, mais autant qu’il y en a de disponible (donc, tester la valeur de retour de get). Ça ne devrait pas présenter de difficulté particulière.

    Une fois que get et put sont maîtrisés, on pourra voir à éventuellement utiliser read et write.

  9. #9
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 169
    Points : 60
    Points
    60
    Par défaut
    exact on veux écrire 1 seul caractère pas "i" caractère....
    Merci !
    Mais ça fonctionne pas non plus, ça me prends 4 caractères juste (surement mes 4 caractères de ma clé "nimp"...) je cherches ça plus tard, je vais retourner chercher avec .put().

    ceci dit, pour mon exemple j'ai fais une boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (int i(0), j(0); i < 10; i++, j++)
    {
    	file.get(texteOrigin);
    	...
    }
    mais je pense faire plus tôt

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (int i(0), j(0); !file.eof(); i++, j++)
    {
    	file.get(texteOrigin);
    	...
    }
    pour lire la totalité du fichier.

    Mais même avec ça, le code est mauvais... merci pour vos aiguillage

  10. #10
    Membre émérite
    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
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par Jeano81 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (int i(0), j(0); !file.eof(); i++, j++)
    {
    	file.get(texteOrigin);
    	...
    }
    pour lire la totalité du fichier.
    Deux choses :
    - ne jamais tester file.eof() pour une boucle. S’il y a une erreur de lecture, eof() peut être à false et ne deviendra jamais vrai. Donc, toujours tester file.good() comme condition d’arrêt d’une boucle
    - i ne sert normalement plus à rien ici.

  11. #11
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 169
    Points : 60
    Points
    60
    Par défaut
    Donc ma boucle for doit ressembler à ceci : ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for (int i(0); file.good(); i++)
    {
    	file.get(texteOrigin);
     
    	if (i > key.size())
    	{
    		i = 0;
    	}
     
    	texteConv.push_back(texteOrigin ^ key[i]);
    	cout << texteConv[texteConv.size()-1];
    }

  12. #12
    Membre émérite
    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
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par Jeano81 Voir le message
    Donc ma boucle for doit ressembler à ceci : ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for (int i(0); file.good(); i++)
    {
    	file.get(texteOrigin);
     
    	if (i > key.size())
    	{
    		i = 0;
    	}
     
    	texteConv.push_back(texteOrigin ^ key[i]);
    	cout << texteConv[texteConv.size()-1];
    }
    Non, toujours pas .

    Il faut tester file.good() après le get. En effet, si on arrive à la fin du fichier, get() va échouer, et donc le caractère ne sera pas changé.

    Un exemple de code serait plutôt :
    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
     
    char c;
    int i = 0;
    file.get(c);
    while(file.good())
    {
        if (i >= key.size())
        {
            i = 0;
        }
        texteConv.push_back(texteOrigin ^ key[i]);
        cout << texteConv[texteConv.size()-1];
        file.get(c);
        ++i;
    }
    Note : utiliser une boucle while plutôt que for est une affaire de style uniquement.
    Note2 : j’ai aussi corrigé le test que me semble erroné — i >= key.size() plutôt que i > key.size()

  13. #13
    Membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 169
    Points : 60
    Points
    60
    Par défaut
    Non d'un canard unijambiste boiteux ! ça fonctionne !!!
    Plus sérieusement ! mon gros souci c'était que je lisais les caractères à partir de ma première boucle alors qu'il faut commencer à l'extérieur pour qu'une fois le caractère de fin lu, ça quitte la boucle, tandis-que comme je faisait ça lisait encore 1 caractère (ou fonctionnait de façon assez aléatoire) de par le fait qu'il lisait encore que le fichier était pas à la fin et de suite après lire un caractère qui n'existait pas me mettait le wail ? en gros c'est ça ?
    Le pire c'est que je me suis demandé si c'était pas une erreur et qu'il me faille le lire avant...

    (le code si il y à des intéresses) :

    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
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
     
    using namespace std;
     
    int main()
    {
    	ifstream file("fichier.txt", ios::in | ios::binary);
    	string key = "nimp";
    	vector <char>  texteConv;
    	char texteOrigin;
     
    	file.get(texteOrigin);
    	for (int i(0); file.good(); i++)
    	{
    		if (i >= key.size())
    		{
    			i = 0;
    		}
     
    		texteConv.push_back(texteOrigin ^ key[i]);
    		cout << texteConv[texteConv.size()-1];
    		file.get(texteOrigin);
    	}
     
    	cout << endl;
     
    	file.close();
     
    	ofstream fileenc("fichier.txt", ios::out | ios::trunc | ios::binary);
     
    	for (int i(0); i < texteConv.size(); i++)
    	{
    		fileenc.write(&texteConv[i],1);
    	}
     
    	system("pause");
    	return 0;
    }
    PS : code à rectifier mais le principe est là.

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

Discussions similaires

  1. Problème sur la recherche fulltext en v4 !
    Par poppa dans le forum Requêtes
    Réponses: 3
    Dernier message: 13/05/2004, 23h06
  2. Problème sur GetPrivateProfileString ???
    Par Bordelique dans le forum Langage
    Réponses: 7
    Dernier message: 25/06/2003, 22h15
  3. Problème sur une requête INSERT
    Par Marion dans le forum Langage SQL
    Réponses: 3
    Dernier message: 17/06/2003, 08h45
  4. problème sur une requête!!!!!
    Par Mcgrady_01 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 13/06/2003, 01h17
  5. [Accents - XML] Problème de codage non supporté !!
    Par Smortex dans le forum Composants VCL
    Réponses: 6
    Dernier message: 24/11/2002, 11h00

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