420KEJ—Client de test, TP00

#ifndef OUTILS_CONVERSION_H
#define OUTILS_CONVERSION_H

#include <sstream>
using std::basic_stringstream;
#include <string>
using std::basic_string;

template <class T, class C>
   T stot (const basic_string<C> &s)
   {
      basic_stringstream<C> sstr (s);
      T val;
      sstr >> val;
      return val;
   }
template <class C, class T>
   basic_string<C> ttos (const T &val)
   {
      basic_stringstream<C> sstr;
      sstr << val;
      return sstr.str ();
   }

#endif

Dans le but de vous aider à tester votre implémentation personnelle du TP00, permettez-moi de vous proposer un petit programme de test tout simple qui sollicitera les fonctionnalités demandées de vos divers petits serveurs de chiffrement de données.

Le programme proposé aura les particularités suivantes :

Vous remarquerez la présence de clauses catch(...). Bien que ce ne soit pas toujours une sage pratique, puisqu'on ne peut pas gérer l'exception survenue, faute d'information, c'est ici l'approche la plus saine du fait que je ne peux pas savoir quels noms vous avez utilisés pour signaler les divers cas problématiques que vous aurez détectés.

Des consignes, en caractères gras, suivent les directives d'inclusion dans le programme de test. Lisez-les attentivement pour connaître la liste des autres adaptations qu'il vous faudra apporter au programme de test proposé pour que celui-ci s'intègre harmonieusement avec votre propre implémentation.

Si vous avez des questions quant à certaines manoeuvres apparaissant dans ce programme, notez-les et on en reparlera en classe.

Amusez-vous bien!

#include "Crypto.h"
#include "ustring.h"
#include "outils_conversion.h"
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::getline;
#include <vector>
using std::vector;

//
// CODE DE TEST POSSIBLE POUR VOTRE BON PLAISIR
//
// Vous pouvez utiliser ce qui suit pour faire des tests quant à votre
// implémentation du TP00. Évidemment, il vous faudra faire quelques
// menus ajustements pour que cela fonctionne. Ainsi, en fonction de
// votre propre implémentation, vous voudrez:
//
// - le nom de la fabrique (j'utilise un singleton nommé FabriqueCrypto,
//   mais je ne sais pas ce que vous faites);
//
// - les sortes d'objets de chiffrement (j'utilise FabriqueCrypto::RotXX,
//   FabriqueCrypto::Circu et FabriqueCrypto::JulesCesar, mais je ne sais
//   pas ce que vous avez choisis de faire);
//
// - dans TesterStrategie(), j'utilise un objet RAII dont le type est
//   FabriqueCrypto::Crypto, une classe interne à FabriqueCrypto, pour
//   automatiser la construction et le nettoyage des ICrypto*. Son
//   constructeur prend la sorte en invoque la fonctiobn de création, et
//   son destructeur libère le pointeur obtenu à la création. La méthode
//   get() de cet objet retourne le ICrypto* qu'il encapsule.
//

void Tester(ICrypto *p)
{
   cout << "Texte pour chiffrement? ";
   ustring entree;
   getline (cin, entree);
   vector<unsigned char>dest (entree.size ());
   copy (entree.begin (), entree.end (), dest.begin());
   try
   {
      p->Chiffrer (entree.c_str (), &dest[0], entree.size ());
      cout << "Texte post-chiffrement: \""
           << ustring (dest.begin (), dest.end ()) << '\"' << endl;
      copy (dest.begin (), dest.end (), entree.begin ());
   }
   catch (...)
   {
      cerr << "Erreur lors du chiffrement de \""
           << entree << '\"' << endl;
      throw;
   }
   try
   {
      p->Dechiffrer (entree.c_str (), &dest[0], entree.size ());
      cout << "Texte post-dechiffrement: \""
           << ustring (dest.begin (), dest.end ()) << '\"' << endl;
   }
   catch (...)
   {
      cerr << "Erreur lors du dechiffrement de \""
           << entree << '\"' << endl;
      throw;
   }
}

void Initialiser (ICrypto *p, const FabriqueCrypto::sorte s)
{
   switch (s)
   {
   case FabriqueCrypto::RotXX:
   case FabriqueCrypto::Circu:
      {
         int nbpos;
         cout << "Nombre de positions? ";
         cin >> nbpos;
         cin.ignore();
         ustring init_txt = ttos<unsigned char>(nbpos);
         p->Initialiser (init_txt.c_str (), init_txt.size ());
      }
      break;
   case FabriqueCrypto::JulesCesar:
      {
         cout << "Chiffre? ";
         ustring init_txt;
         getline (cin, init_txt);
         p->Initialiser (init_txt.c_str (), init_txt.size ());
      }
      break;
   }
}

#include <string>
using std::string;

void TesterStrategie (const FabriqueCrypto::sorte s, const string &nom)
{
   FabriqueCrypto::Crypto chiff (s);
   if (chiff.get ())
   {
      cout << nom << "... ";
      try
      {
         Initialiser (chiff.get (), s);
      }
      catch (...)
      {
         cerr << nom << ": echec lors de l'initialisation" << endl;
         return;
      }
      try
      {
         Tester (chiff.get ());
      }
      catch (...)
      {
         cerr << nom << ": echec" << endl;
      }
   }
}

int main ()
{
   TesterStrategie (FabriqueCrypto::RotXX, "RotXX");
   TesterStrategie (FabriqueCrypto::Circu, "Circu");
   TesterStrategie (FabriqueCrypto::JulesCesar, "JulesCesar");
}