Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1284 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Algorithme de vigenere modifié

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Algorithme de vigenere modifié

n°2162142
ehounsou
Posté le 31-10-2012 à 18:46:45  profilanswer
 

Bonjour  
Je suis novice en programmation c. Je souhaite, dans le cadre d'un travail de recherche à présenter, écrire un programme de cryptage par la méthode de vigenère. le plus de mon algorithme est qu'il devra prendre en compte les caractères accentués, les chiffres les espaces ainsi que les ponctuations de la langue française (à,é,è,ê,ç, ù,1,2,3,4,5,6,7,8,9,0).
j'ai pu écrire l'algorthme suivant mais je n'arrive pas a extraire le resultat du texte chiffré pour l'afficher a l'ecran. ce resultat se trouve en principe dans le tableau cod.
 
Ci dessous l'algorithme.
 

Code :
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<ctype.h>
  5. #include <wchar.h>
  6. wchar_t Alpha[] = {L"abcdefghijklmnopqrstuvwxyz@0123456789 ,;:!?.%c133%c130%c138%c136%c151%c135%c147%c131"};
  7. wchar_t Cle []={};
  8. wchar_t Acoder []={}, cod[]={};
  9. int i, t, u;
  10. int PosCle =0;
  11. wchar_t *PosLetCle; //pointeur sur la position de la lettre cle
  12. wchar_t *Pos; //Pointeur sur la position de la lettre dans la pgrase
  13. int NouvPos=0; //nouvelle position qui determinera la lettre correspondant au chiffrement
  14. //int choix, nombre;
  15. wchar_t LetCle; // la lettre dans la clé de chiffrement
  16. wchar_t Let, Lettre; //La lettre dans la phrae à coder
  17. int main()
  18. {
  19.         wprintf (L"n Veuillez saisir la phrase %c crypter:n ", 133 );
  20.         wscanf(L"%ls", Acoder);
  21.         wprintf (L"n Entrez la cle de codage de la phrase: n" );
  22.         wscanf(L"%ls", Cle);
  23.         t = wcslen(Acoder);// longueur de la phrase saisie au clavier
  24.         u = wcslen(Cle); //Longueur de la clé de chiffrement
  25.             for (i=0; i<t ; i++)
  26.                 {
  27.                     PosCle= PosCle+1;
  28.                     if (PosCle>u)
  29.                     PosCle=1;
  30.         /* on determine quelle est la lettre cle et sa position dans l'alphabet que nous avons définit en prenant en compte les caractère acceutué */
  31.                     LetCle = Cle[PosCle];
  32.                     PosLetCle = wcschr(Alpha, LetCle); //on renvoie un pointeur sur la première occurence de Letclé que l'on trouve dans Alpha equivaut a strchr en C
  33.                     /* on determine la position de la lettre a coder et le decalage a appliquer */
  34.                     Let = Acoder[i];
  35.                     Pos = wcschr(Alpha, Let);
  36.                     NouvPos = *Pos + *PosLetCle;
  37.                     if (NouvPos > 52)
  38.                     NouvPos = NouvPos - 52;
  39.                     cod[i]= Alpha[NouvPos];
  40.                 }
  41.                 cod[i]= '';
  42. wprintf(L"la phrase codee est: %lsn", cod);
  43. }


Je sollicite votre indulgence et espère avoir un retour assez rapidement  
Merci


Message édité par gilou le 07-11-2012 à 15:40:02
mood
Publicité
Posté le 31-10-2012 à 18:46:45  profilanswer
 

n°2162154
Farian
Posté le 31-10-2012 à 22:17:46  profilanswer
 

Votre détermination de la nouvelle position n'est pas bonne, car la fonction "wcschr" renvoie un pointeur sur la position et, par construction (si le retour n'est pas nul) *Pos = Let et *PosLetCle = LetCle.
 
Pour la nouvelle position, vous ajoutez donc deux wchar et vous vous servez de la somme comme index dans le tableau Alpha, ce qui n'est pas correct.
 
Vous devriez utiliser une fonction qui renvoie le premier index du caractère dans la chaine (au pire vous l'écrivez vous-même, cela prend environ 30 secondes) et cela marchera mieux.
 
Par ailleurs, sauf erreur de ma part, vos allocations initiales de chaînes de type  "wchar_t Acoder []={}"  allouent un pointeur sur une zone de 1*sizeof(wchar_t) (pour mettre le 0 final) et faire des wscanf dessus ne peut que provoquer des choses douteuses en mémoire ... Allouez les à une taille "énorme" (1024 par exemple) et cela devrait éviter des soucis.

n°2162730
ehounsou
Posté le 06-11-2012 à 14:38:54  profilanswer
 

Bonjour
J'ai essayé d'apporter les modifications mais le code ne donne pas le resultat escompté. Ci dessous le code
 

Code :
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<ctype.h>
  5. #include <wchar.h>
  6. wchar_t Alpha[] = {L"abcdefghijklmnopqrstuvwxyz%c133%c130%c138%c136 %c151%c135%c147"};
  7. //wchar_t Alpha[] = {L"abcdefghijklmnopqrstuvwxyz"};
  8. wchar_t Cle [50];
  9. wchar_t Acoder [200], cod[200];
  10. int lgtext, lgclef;
  11. int PosCle =0;
  12. int NouvPos=0; //nouvelle position qui determinera la lettre correspondant au chiffrement
  13. wchar_t LetCle; // la lettre dans la clé de chiffrement
  14. wchar_t Let; //La lettre dans la phrae à coder
  15. int search (wchar_t *s , wchar_t carac)
  16. {
  17. int i;
  18. for(i = 0; s[i] != '';i++)
  19.  if(s[i] == carac)
  20.   return i;
  21. return 0;
  22. }
  23. int main()
  24. {
  25.         int i;
  26.         wprintf (L"n Veuillez saisir la phrase %c crypter:n", 133 );
  27.         wscanf(L"%ls", Acoder);
  28.         wprintf (L"n Entrez la cle de codage de la phrase: n" );
  29.         wscanf(L"%ls", Cle);
  30.         lgtext = wcslen(Acoder);// longueur de la phrase saisie au clavier
  31.         lgclef = wcslen(Cle); //Longueur de la clé de chiffrement
  32.             for (i=0; i< lgtext ; i++)
  33.                 {
  34.                     PosCle= PosCle+1;
  35.                     if (PosCle>lgclef)
  36.                     PosCle=1;
  37.         /* on determine quelle est la lettre cle et sa position dans l'alphabet que nous avons définit en prenant en compte les caractère acceutué */
  38.                     LetCle = Cle[PosCle];
  39.                     /* on determine la position de la lettre a coder et le decalage a appliquer */
  40.                     Let = Acoder[i];
  41.                     int pos = search (Alpha,LetCle);
  42.                     int pos1 = search (Alpha,Let);
  43.                     NouvPos = pos+pos1;
  44.                     if (NouvPos > 40)
  45.                     NouvPos = NouvPos - 40;
  46.                     cod[i]= Alpha[NouvPos];
  47.                 }
  48. wprintf(L"la phrase codee est: %lsn", cod);
  49. }


pouvez vous me dire ce qui ne vas pas ?


Message édité par gilou le 07-11-2012 à 15:40:22
n°2162732
Farian
Posté le 06-11-2012 à 14:50:48  profilanswer
 

Bonjour ! Sauf erreur de ma part, votre tableau Alpha ne fait que 34 caractères (les 26 lettres, plus l'espace, plus les codes 133, 130, 138, 136, 151, 135 et 147), et dans votre test, vous comparez les index à 40 ...
 
Pour PosCle, vous devriez démarrer à 0 et non pas à 1 (et recommencer à 0) et tester si PosCle est >= lgclef
 
Pourquoi ne pas tester dynamiquement la taille de ce tableau pour savoir si vous devez boucler ? Cela vous permettra de rajouter des caractères sans avoir à modifier le reste du code et, et c'est le plus important, cela assure que vous ne sortez pas du tableau.
 
Edit : Le fait qu'un caractère de la clé ou du message à chiffrer ne soit pas dans les lettres autorisées n'est pas géré (a priori, le code fait la même chose que si c'était un "a" ).


Message édité par Farian le 06-11-2012 à 14:54:51
n°2162747
ehounsou
Posté le 06-11-2012 à 15:49:45  profilanswer
 

En plus des caractères accentué (à,é,è,ù,ô,ê) nous avon voulu aussi gérer les ponctuation (?.!,;:) ce qui emmenne le nombre d'élément du tableau à 40 caractères. pour la gestion des erreurs en cas de caractères non autorisés saisi, je n'ai pas encore pensé gérer cela. J'ai modifié le code en gérant dynamiquement le test sur la taille du tableau cependant mon codage de vigenere ne me retourne pas le resultat attendu.
Ci dessous l'algo corrigé
 

Code :
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<ctype.h>
  5. #include <wchar.h>
  6. wchar_t Alpha[] = {L"abcdefghijklmnopqrstuvwxyz%c133%c130%c138%c136 %c151%c135%c147?!.,;:"};
  7. wchar_t Cle [50];
  8. wchar_t Acoder [200], cod[200];
  9. int lgtext, lgclef, lgalpha;
  10. int PosCle =0;
  11. int NouvPos=0;
  12. wchar_t LetCle;
  13. wchar_t Let;
  14. int search (wchar_t *s , wchar_t carac)
  15. {
  16. int i;
  17. for(i = 0; s[i] != '';i++)
  18.  if(s[i] == carac)
  19.   return i;
  20. return 0;
  21. }
  22. int main()
  23. {
  24.         int i;
  25.         wprintf (L"n Veuillez saisir la phrase %c crypter:n", 133 );
  26.         wscanf(L"%ls", Acoder);
  27.         wprintf (L"n Entrez la cle de codage de la phrase: n" );
  28.         wscanf(L"%ls", Cle);
  29.         lgtext = wcslen(Acoder);// longueur de la phrase saisie au clavier
  30.         lgclef = wcslen(Cle); //Longueur de la clé de chiffrement
  31.         lgalpha = wcslen (Alpha);
  32.             for (i=0; i< lgtext ; i++)
  33.                 {
  34.                     PosCle= PosCle+1;
  35.                     if (PosCle>=lgclef)
  36.                     PosCle=0;
  37.                     LetCle = Cle[PosCle];
  38.                     Let = Acoder[i];
  39.                     int pos = search (Alpha,LetCle);
  40.                     int pos1 = search (Alpha,Let);
  41.                     NouvPos = pos+pos1;
  42.                     if (NouvPos > lgalpha)
  43.                     NouvPos = NouvPos - lgalpha;
  44.                     cod[i]= Alpha[NouvPos];
  45.                 }
  46. wprintf(L"la phrase codee est: %lsn", cod);
  47. }


Message édité par gilou le 07-11-2012 à 15:40:41
n°2162760
Farian
Posté le 06-11-2012 à 16:18:34  profilanswer
 

Re-bonjour  
 
Sauf erreur de ma part, il manque l'initialisation de PosCle. De plus, le test doit être if (NouvPos >= lgalpha), pour rester dans l'intervalle entre [0, longueurChaine-1].
 
Le reste parait bien, à première vue. Pour vérifier, si le résultat n'est toujours pas bon, faites afficher les chaines Cle et ACoder et postez le résultat ...
 
Bonne finalisation !

n°2162767
ehounsou
Posté le 06-11-2012 à 16:43:19  profilanswer
 

PosCle a été initialisé lors de sa déclaration à la ligne 10 par int PosCle =0;
 
L'affichage des chaînes donne le résultat suivant  
 
 Veuillez saisir la phrase à crypter:
bienvenue
 
 Entrez la cle de codage de la phrase:
test
la phrase codee est: f%xczwc3i
la phrase a chiffrer est: bienvenue
La cle de chiffrement est: test
 
La phrase codé n'est pas correct. En prenant le tableau définie dans Alpha et en appliquant les principe de vigenère, on devrai obtenir avec le mot "bienvenue" et la clé "test" le code suivant : umwçaiù:x

n°2162797
Farian
Posté le 06-11-2012 à 18:16:59  profilanswer
 

En effet, j'avais mal vu pour l'initialisation :)
 
Ensuite, je pense que deux problèmes se télescopent :  
 
 * Vous incrémentez PosCle avant toute utilisation, ce qui fait que vous démarrez au premier caractère "e" au lieu d'utiliser "t" pour le décalage du premier caractère => le "u" que vous deviez obtenir devient un "f", ce qui paraît correct => Soit vous initialisez PosCle à -1 (bof ...), soit vous décalez votre incrémentation après la ligne "LetCle = Cle[PosCle]; "
 
 * Je ne suis pas du tout habitué aux wchar, mais l'impression que cela me donne est que le %c133 n'est pas remplacé dans la définition de la variable Alpha (ce qui paraît normal ...). Le mieux serait de déclarer cette variable comme les autres wchar_t Alpha[200]; et effectuer un wsprintf (ou équivalent) pour la remplir, je pense que cela marcherait.
 
Vous pouvez rapidement tester le second point en limitant le jeu de caractères dans Alpha aux caractères "normaux" et voir si le résultat est correct.

n°2162882
ehounsou
Posté le 07-11-2012 à 09:04:03  profilanswer
 

Bonjour  
Merci pour votre aide précieuse cela m'a permis de corriger le code et j'obtient maintenant le résultat escompté. j'ai remplacé les valeur %133, % 131 .... par leur équivalent en hexadecimal en les definissant comme x85 x83 .....
Cependant un problème subsiste toujours. lorsque je décide de rentré ma phrase à codé en y incluant des espaces la c'est le comble le programme ne fonctionne plus comme cela devrait. un exemple :
en voulant codé le texte : bienvenue au pays avec la clé test, j'ai le résultat suivant
la phrase codee est: bèeôvynae
la phrase a chiffrer est: bienvenue
La cle de chiffrement est: au
 
le programme considère le mot après l'espace comme la clé, ignore le troisième mot (pays) et ne demande même pas de saisir la clé et me retourne le résultat mentionné ci dessus.
 
Comment pourrais je corriger le code pour prendre en compte l'espace. J'ai essayé d'ajouter dans la déclaration d'Alpha le code hexa d'espace (x20) mais cela n'a rien changé
 
Ci dessous le code  
 

Code :
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<ctype.h>
  5. #include <wchar.h>
  6. wchar_t Alpha[] = {L"abcdefghijklmnopqrstuvwxyzx85x82x8Ax88x20x97x87x93?!.,;:"};
  7. //wchar_t Alpha[] = {L"abcdefghijklmnopqrstuvwxyz%c133%c130%c138%c136 %c151%c135%c147?!.,;:"};
  8. //wchar_t Alpha[] = {L"abcdefghijklmnopqrstuvwxyz"};
  9. wchar_t Cle [50];
  10. wchar_t Acoder [200], cod[200];
  11. int lgtext, lgclef, lgalpha;
  12. int PosCle =-1;
  13. int NouvPos=0; //nouvelle position qui determinera la lettre correspondant au chiffrement
  14. wchar_t LetCle; // la lettre dans la clé de chiffrement
  15. wchar_t Let; //La lettre dans la phrae à coder
  16. int search (wchar_t *s , wchar_t carac)
  17. {
  18. int i;
  19. for(i = 0; s[i] != '';i++)
  20.  if(s[i] == carac)
  21.   return i;
  22. return 0;
  23. }
  24. int main()
  25. {
  26.         int i;
  27.         wprintf (L"n Veuillez saisir la phrase %c crypter:n", 133 );
  28.         wscanf(L"%ls", Acoder);
  29.         wprintf (L"n Entrez la cle de codage de la phrase: n" );
  30.         wscanf(L"%ls", Cle);
  31.         lgtext = wcslen(Acoder);// longueur de la phrase saisie au clavier
  32.         lgclef = wcslen(Cle); //Longueur de la clé de chiffrement
  33.         lgalpha = wcslen (Alpha);
  34.             for (i=0; i< lgtext ; i++)
  35.                 {
  36.                     PosCle= PosCle+1;
  37.                     if (PosCle>=lgclef)
  38.                     PosCle=0;
  39.         /* on determine quelle est la lettre cle et sa position dans l'alphabet que nous avons définit en prenant en compte les caractère acceutué */
  40.                     LetCle = Cle[PosCle];
  41.                     /* on determine la position de la lettre a coder et le decalage a appliquer */
  42.                     Let = Acoder[i];
  43.                     int pos = search (Alpha,LetCle);
  44.                     int pos1 = search (Alpha,Let);
  45.                     NouvPos = pos+pos1;
  46.                     if (NouvPos >= lgalpha)
  47.                     NouvPos = NouvPos - lgalpha;
  48.                     cod[i]= Alpha[NouvPos];
  49.                 }
  50. wprintf(L"la phrase codee est: %lsn", cod);
  51. wprintf (L"la phrase a chiffrer est: %lsn", Acoder);
  52. wprintf (L"La cle de chiffrement est: %lsn", Cle);
  53. }


Message édité par gilou le 07-11-2012 à 15:41:00
n°2162921
Farian
Posté le 07-11-2012 à 10:50:32  profilanswer
 

Bonjour !  
 
C'est le défaut avec scanf quand on lui passe une chaîne, il s'arrête au premier espace ... Je vous conseille de faire un fgets (ou son équivalent wchar) pour pouvoir saisir une valeur contenant des espaces (attention, il vous faudra peut-être enlever le retour chariot final).

mood
Publicité
Posté le 07-11-2012 à 10:50:32  profilanswer
 

n°2162986
ehounsou
Posté le 07-11-2012 à 13:01:54  profilanswer
 

ok je vois et je comprend mieux l'usage de scanf. j'ai modifié le programme mais une dernière erreur persiste. Après exécution, je remarque que le premier caractère de la clé est omis lors du processus de cryptage. J'obtient alors le resultat suivant  
 
 
 ***** Cryptage et Decryptage de Vigenere *****
 
 Merci de faire un choix
 
 [1] pour le cryptage
 [2] pour le decryptage
1
Veuillez saisir la phrase à crypter:bienvenue à esgis
Entrez la cle de codage de la phrase:test
la phrase codee est: fàxr:xr;x?eji.zm.
la phrase a chiffrer est: bienvenue à esgis
La cle de chiffrement est: est
 
 
Il prend comme clé de chiffrement 'est' alors que j'ai rentré 'test'
 
ci dessous le programme que j'ai exécuté
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <wchar.h>
  6. wchar_t Alpha[] = {L"abcdefghijklmnopqrstuvwxyzx85x82x8Ax88x20x97x87x93?!.,;:"};
  7. wchar_t Cle [200];
  8. wchar_t Acoder [200], cod[200];
  9. int lgtext, lgclef, lgalpha;
  10. int PosCle =-1;
  11. int NouvPos; //nouvelle position qui determinera la lettre correspondant au chiffrement
  12. wchar_t LetCle; // la lettre dans la clé de chiffrement
  13. wchar_t Let; //La lettre dans la phrae à coder
  14. void chiffrement ();
  15. void dechiffrement();
  16. int search (wchar_t *s , wchar_t carac)
  17. {
  18. int i;
  19. for(i = 0; s[i] != '';i++)
  20.  if(s[i] == carac)
  21.   return i;
  22. return 0;
  23. }
  24. static void purger(void)
  25. {
  26.     int c;
  27.     while ((c = getwchar()) != 'n' && c != EOF)
  28.     {}
  29. }
  30. static void clean (wchar_t *chaine)
  31. {
  32.     wchar_t *p = wcschr(chaine, 'n');
  33.     if (p)
  34.     {
  35.         *p = 0;
  36.     }
  37.     else
  38.     {
  39.         purger();
  40.     }
  41. }
  42. int main ()
  43. {
  44. printf ("n ***** Cryptage et Decryptage de Vigenere *****n";);
  45. printf ("n Merci de faire un choixn";);
  46. printf ("n [1] pour le cryptage n [2] pour le decryptage n";);
  47. int action;
  48. scanf ("%d", &action);
  49.         if (action ==1)
  50.             {
  51.             chiffrement();
  52.             }
  53.         else
  54.                 if (action==2)
  55.                 {
  56.                 dechiffrement();
  57.                 }
  58.         else
  59.             {
  60.             printf ("n Veuillez choisir un nombre entre 1 et 2n" );
  61.             }
  62.         return 0;
  63. }
  64. void chiffrement ()
  65. {
  66.         int i;
  67.         wprintf (L"Veuillez saisir la phrase %c crypter:", 133 );
  68.         fgetc(stdin);
  69.      fgetws(Acoder, sizeof Acoder, stdin);
  70.      clean(Acoder);
  71.         //wscanf(L"%ls", Acoder);
  72.         wprintf (L"Entrez la cle de codage de la phrase:" );
  73.         fgetc(stdin);
  74.      fgetws(Cle, sizeof Cle, stdin);
  75.      clean(Cle);
  76.         lgtext = wcslen(Acoder);// longueur de la phrase saisie au clavier
  77.         lgclef = wcslen(Cle); //Longueur de la clé de chiffrement
  78.         lgalpha = wcslen (Alpha);
  79.             for (i=0; i< lgtext ; i++)
  80.                 {
  81.                     PosCle= PosCle+1;
  82.                     if (PosCle>=lgclef)
  83.                     PosCle=0;
  84.         /* on determine quelle est la lettre cle et sa position dans l'alphabet que nous avons définit en prenant en compte les caractère acceutué */
  85.                     LetCle = Cle[PosCle];
  86.                     /* on determine la position de la lettre a coder et le decalage a appliquer */
  87.                     Let = Acoder[i];
  88.                     int pos = search (Alpha,LetCle);
  89.                     int pos1 = search (Alpha,Let);
  90.                     NouvPos = pos+pos1;
  91.                     if (NouvPos >= lgalpha)
  92.                     NouvPos = NouvPos - lgalpha;
  93.                     cod[i]= Alpha[NouvPos];
  94.                 }
  95.   wprintf(L"la phrase codee est: %lsn", cod);
  96.         wprintf (L"la phrase a chiffrer est: %lsn", Acoder);
  97.         wprintf (L"La cle de chiffrement est: %lsn", Cle);
  98. }
  99. void dechiffrement()
  100. {
  101. int i;
  102.         wprintf (L"n Veuillez saisir la phrase %c dechiffrer:n", 133 );
  103.         fgetc(stdin);
  104.      fgetws(cod, sizeof cod, stdin);
  105.      clean(cod);
  106.         //wscanf(L"%ls", cod);
  107.         wprintf (L"n Entrez la cle de decodage de la phrase: n" );
  108.         fgetc(stdin);
  109.      fgetws(Cle, sizeof Cle, stdin);
  110.      clean(Cle);
  111.         //wscanf(L"%ls", Cle);
  112.         lgtext = wcslen(cod);
  113.         lgclef = wcslen(Cle);
  114.         lgalpha = wcslen (Alpha);
  115.             for (i=0; i< lgtext ; i++)
  116.                 {
  117.                     PosCle= PosCle+1;
  118.                     if (PosCle>=lgclef)
  119.                     PosCle=0;
  120.         /* on determine quelle est la lettre cle et sa position dans l'alphabet que nous avons définit en prenant en compte les caractère acceutué */
  121.                     LetCle = Cle[PosCle];
  122.                     /* on determine la position de la lettre a décoder et le decalage a appliquer */
  123.                     Let = cod[i];
  124.                     int pos = search (Alpha,LetCle);
  125.                     int pos1 = search (Alpha,Let);
  126.                     NouvPos = pos1 - pos;
  127.                     if (NouvPos < 0)
  128.                     NouvPos = lgalpha - abs(NouvPos);
  129.                     Acoder[i]= Alpha[NouvPos];
  130.                 }
  131.   wprintf(L"la phrase initial est: %lsn", Acoder);
  132.   wprintf(L"la phrase codee est: %lsn", cod);
  133.         wprintf (L"La cle de chiffrement est: %lsn", Cle);
  134. }


Message édité par gilou le 07-11-2012 à 15:41:27
n°2163002
Farian
Posté le 07-11-2012 à 14:00:07  profilanswer
 

Pourquoi faites-vous un fgetc(stdin) avant le fgetws ? C'est sans doute lui qui "mange" le premier caractère de la saisie (donc de la clé).

n°2163010
ehounsou
Posté le 07-11-2012 à 14:36:29  profilanswer
 

Merci pour votre précieuse aide . Le code fonctionne à présent . ci dessous le code .
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <wchar.h>
  6. wchar_t Alpha[] = {L"abcdefghijklmnopqrstuvwxyzx85x82x8Ax88x20x97x87x93?!.,;:"};
  7. wchar_t Cle [200];
  8. wchar_t Acoder [200], cod[200];
  9. int lgtext, lgclef, lgalpha;
  10. int PosCle =-1;
  11. int NouvPos; //nouvelle position qui determinera la lettre correspondant au chiffrement
  12. wchar_t LetCle; // la lettre dans la clé de chiffrement
  13. wchar_t Let; //La lettre dans la phrae à coder
  14. void chiffrement ();
  15. void dechiffrement();
  16. int search (wchar_t *s , wchar_t carac)
  17. {
  18.     int i;
  19.     for(i = 0; s[i] != ''; i++)
  20.         if(s[i] == carac)
  21.             return i;
  22.     return 0;
  23. }
  24. static void purger(void)
  25. {
  26.     int c;
  27.     while ((c = getchar()) != 'n' && c != EOF)
  28.         {}
  29. }
  30. static void clean (wchar_t *chaine)
  31. {
  32.     wchar_t *p = wcschr(chaine, 'n');
  33.     if (p)
  34.     {
  35.         *p = 0;
  36.     }
  37.     else
  38.     {
  39.         purger();
  40.     }
  41. }
  42. int main ()
  43. {
  44.     printf ("n ***** Cryptage et Decryptage de Vigenere *****n"mdss[ {;)}];
  45.     printf ("n Merci de faire un choixn"mdss[ {;)}];
  46.     printf ("n [1] pour le cryptage n [2] pour le decryptage n"mdss[ {;)}];
  47.     int action;
  48.     scanf ("%d", &action);
  49.     if (action ==1)
  50.     {
  51.         chiffrement();
  52.     }
  53.     else if (action==2)
  54.     {
  55.         dechiffrement();
  56.     }
  57.     else
  58.     {
  59.         printf ("n Veuillez choisir un nombre entre 1 et 2n" );
  60.     }
  61.     return 0;
  62. }
  63. void chiffrement ()
  64. {
  65.     int i;
  66.     wprintf (L"Veuillez saisir la phrase %c crypter:", 133 );
  67.     rewind(stdin);
  68.     fgetws(Acoder, sizeof Acoder, stdin);
  69.     clean(Acoder);
  70.     //wscanf(L"%ls", Acoder);
  71.     wprintf (L"Entrez la cle de codage de la phrase:" );
  72.     rewind(stdin);
  73.     fgetws(Cle, sizeof Cle, stdin);
  74.     clean(Cle);
  75.     lgtext = wcslen(Acoder);// longueur de la phrase saisie au clavier
  76.     lgclef = wcslen(Cle); //Longueur de la clé de chiffrement
  77.     lgalpha = wcslen (Alpha);
  78.     for (i=0; i< lgtext ; i++)
  79.     {
  80.         PosCle= PosCle+1;
  81.         if (PosCle>=lgclef)
  82.             PosCle=0;
  83.         /* on determine quelle est la lettre cle et sa position dans l'alphabet que nous avons définit en prenant en compte les caractère acceutué */
  84.         LetCle = Cle[PosCle];
  85.         /* on determine la position de la lettre a coder et le decalage a appliquer */
  86.         Let = Acoder[i];
  87.         int pos = search (Alpha,LetCle);
  88.         int pos1 = search (Alpha,Let);
  89.         NouvPos = pos+pos1;
  90.         if (NouvPos >= lgalpha)
  91.             NouvPos = NouvPos - lgalpha;
  92.         cod[i]= Alpha[NouvPos];
  93.     }
  94.     wprintf(L"la phrase codee est: %lsn", cod);
  95.     wprintf (L"la phrase a chiffrer est: %lsn", Acoder);
  96.     wprintf (L"La cle de chiffrement est: %lsn", Cle);
  97. }
  98. void dechiffrement()
  99. {
  100.     int i;
  101.     wprintf (L"n Veuillez saisir la phrase %c dechiffrer:n", 133 );
  102.     fgetc(stdin);
  103.     fgetws(cod, sizeof cod, stdin);
  104.     clean(cod);
  105.     //wscanf(L"%ls", cod);
  106.     wprintf (L"n Entrez la cle de decodage de la phrase: n" );
  107.     //fgetc(stdin);
  108.     fgetws(Cle, sizeof Cle, stdin);
  109.     clean(Cle);
  110.     //wscanf(L"%ls", Cle);
  111.     lgtext = wcslen(cod);
  112.     lgclef = wcslen(Cle);
  113.     lgalpha = wcslen (Alpha);
  114.     for (i=0; i< lgtext ; i++)
  115.     {
  116.         PosCle= PosCle+1;
  117.         if (PosCle>=lgclef)
  118.             PosCle=0;
  119.         /* on determine quelle est la lettre cle et sa position dans l'alphabet que nous avons définit en prenant en compte les caractère acceutué */
  120.         LetCle = Cle[PosCle];
  121.         /* on determine la position de la lettre a décoder et le decalage a appliquer */
  122.         Let = cod[i];
  123.         int pos = search (Alpha,LetCle);
  124.         int pos1 = search (Alpha,Let);
  125.         NouvPos = pos1 - pos;
  126.         if (NouvPos < 0)
  127.             NouvPos = lgalpha - abs(NouvPos);
  128.         Acoder[i]= Alpha[NouvPos];
  129.     }
  130.     wprintf(L"la phrase initial est: %lsn", Acoder);
  131.     wprintf(L"la phrase codee est: %lsn", cod);
  132.     wprintf (L"La cle de chiffrement est: %lsn", Cle);
  133. }

Message cité 1 fois
Message édité par gilou le 07-11-2012 à 15:45:53
n°2163176
gilou
Modérateur
Modzilla
Posté le 08-11-2012 à 11:40:56  profilanswer
 

ehounsou a écrit :

Merci pour votre précieuse aide . Le code fonctionne à présent .


Non, j'ai recompilé et testé sur ma machine, et il ne fonctionne pas correctement dans mon environnement.
Il y a plusieurs raisons manifestes:
1- C'est un programme en mode console. La console que vous utilisez est sous quel système? (chez moi sous Windoxs XP US, c'est la page de code DOS 437)
    Si c'est un programme en mode console sous Windows, (ce que me laisse penser votre rewind(stdin) qui n'a aucune assurance de fonctionner dans d'autres environnements) il n'y a aucune raison particulière pour que l'input soit en wide-char (l'input de ma console est en char).
   Bon, avec le compilateur de Microsoft, et un appel à _setmode, on peut y remédier (si tant est que la fenêtre console a les fontes Lucida activées, ce qui n'est pas le défaut).
2- Le plus gros problème est dans les algos de cryptage/décryptage, qui dépendent de search, laquelle renvoie une valeur pour tout caractère, même s'il ne figure pas dans l'alphabet de codage (par exemple les majuscules, avec votre alphabet).
    Pour corriger cela, faire renvoyer -1 à search, et dans vos algos, quand on tombe sur cette valeur de -1, mette la lettre en entrée identique à celle de sortie, tout en avançant la clé.
Soit quelque chose comme ceci dans l'algo de cryptage:

Code :
  1. Let = Acoder[i];
  2. int pos = search(Alpha, LetCle);
  3. int pos1 = search(Alpha, Let);
  4. if (pos1 < 0) {
  5.     cod[i]= Let;
  6. }
  7. else {
  8.     NouvPos = pos + pos1;
  9.     if (NouvPos >= lgalpha)
  10.         NouvPos = NouvPos - lgalpha;
  11.     cod[i]= Alpha[NouvPos];
  12. }


 
Il y a d'autres problèmes, mais mineurs.
 
A+,


Message édité par gilou le 08-11-2012 à 11:56:38

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2163190
Farian
Posté le 08-11-2012 à 13:04:50  profilanswer
 

Vous devriez tester les deux valeurs de retour, gilou, car avec ce code là, le piège à bug est armé !  
 
Cas : pos = -1 (caractère non conforme entré dans la clé)
         pos1 = 0 (caractère 'a' dans le message à chiffrer)
 
Pas la peine de vous faire un dessin pour la suite :) (même si on ne fera que lire au mauvais endroit dans la pile, ce qui ne devrait pas être trop méchant ...)
 
Pour être tout à fait honnête, j'avais vu cette source de problème dans les premières version du code, mais comme le code fourni ne présentait pas de risque (retour 0 si caractère inconnu, comme pour 'a'), j'avais laissé filer :)

n°2163198
gilou
Modérateur
Modzilla
Posté le 08-11-2012 à 14:01:13  profilanswer
 

Farian a écrit :

Vous devriez tester les deux valeurs de retour, gilou, car avec ce code là, le piège à bug est armé !


A priori avec une définition de search comme:

Code :
  1. int search(wchar_t *s , wchar_t c) {
  2.     int i;
  3.     for (i = 0; s[i] != L'\0'; i++)
  4.         if (s[i] == c)
  5.             return i;
  6.     return -1;
  7. }


je ne pense pas qu'il y ait de problème.
De toute façon, l'emploi de wcschr et d'une différence de pointeurs me semble plus adaptée que cette fonction ad-hoc.
 

Citation :

mais comme le code fourni ne présentait pas de risque

Certes, mais on ne peut plus décoder correctement, puisqu'on tout caractère hors de l'alphabet va alors être décodé comme un a, puisqu'il y est identifié au moment du codage.
A+,


Message édité par gilou le 08-11-2012 à 14:04:38

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2163226
Farian
Posté le 08-11-2012 à 18:41:38  profilanswer
 

Le problème potentiel vient du fait que l'on peut avoir pos1=0 et pos = -1, le problème ne venant pas de la fonction search (qui parait très correcte) mais du fait que l'ensemble dans lequel on recherche l'index d'un caractère de la clé dans un sous-ensemble (la chaîne Alpha) et que l'opérateur peut très bien saisir "cle0" comme clé (les chiffres ne sont pas gérés dans le code fourni).
 
Pour le deuxième point, entièrement d'accord avec vous :D

n°2163228
gilou
Modérateur
Modzilla
Posté le 08-11-2012 à 18:57:08  profilanswer
 

Pour le premier point, tout à fait.
Mais il semblerait logique que la cohérence de la clé vis à vis de l'alphabet (voire même d'une partie de cet alphabet) soit exigée et vérifiée avant de commencer le codage (sinon, on peut toujours tomber sur le cas ou la clé n'est constituée que de caractères hors de l'alphabet, cas pour lequel je ne vois pas de solution de secours applicable).
A+,


Message édité par gilou le 08-11-2012 à 18:58:27

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Algorithme de vigenere modifié

 

Sujets relatifs
Algorithme Compression/DécompressionAlgorithme mastermind.
poblème d'algorithme franceioiDate modifié à la sauvegarde en DB
Commande SQL qui ne modifie qu'une seule ligne...explication d'un algorithme ada
Algorithme Glouton[RESOLU] Theme, css modifié, blog disparu
algorithme pour trier un tableaualgorithme sur des segments
Plus de sujets relatifs à : Algorithme de vigenere modifié


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR