Cryptage Carré de Polybe...
2 participants
Page 1 sur 1
Cryptage Carré de Polybe...
Bon, je sais pas si cette section est le plus adaptée, mais je poste mon code... Si vous pouviez m'aider à l'optimiser, l'améliorer, et me dire si la mise en forme (indentation etc.) est bonne ?
- Code:
/* main.c */
#include "polybe.h"
#include <stdio.h>
#define MAX 1000
int main(void)
{
char s_phraseACrypter[MAX];
char s_phraseCryptee[MAX];
int i;
printf("Entrez la phrase a crypter:\n");
fgets(s_phraseACrypter, MAX, stdin);
crypterPolybe(s_phraseACrypter, s_phraseCryptee);
printf("Voici la phrase cryptee:\n");
for (i = 0 ; s_phraseACrypter[i] ; i++)
{
printf("%d ", s_phraseCryptee[i]);
}
printf("\n");
return 0;
}
- Code:
/* polybe.c */
#include "polybe.h"
#include <string.h>
void crypterPolybe(char *s_phraseACrypter, char *s_phraseCryptee)
{
int i = 0;
char *p = strchr(s_phraseACrypter, '\n');
if (p != NULL)
{
*p = 0;
}
do
{
int c = s_phraseACrypter[i] - 'a';
if (s_phraseACrypter[i] >= 'a' && s_phraseACrypter[i] <= 'v')
{
s_phraseCryptee[i] = c + 11 + 5*(c/5);
}
else if (s_phraseACrypter[i] >= 'w' && s_phraseACrypter[i] <= 'z')
{
c--;
s_phraseCryptee[i] = c + 11 + 5*(c/5);
}
else
{
s_phraseCryptee[i] = 0;
}
i++;
} while (s_phraseACrypter[i]);
}
- Code:
#ifndef H_POLYBE
#define H_POLYBE
/* polybe.h */
void crypterPolybe(char *, char *);
#endif /* guard */
Dernière édition par -ed- le Mar 18 Nov 2008 - 11:52, édité 1 fois (Raison : Mise en forme)
azerty- Bavard
- Messages : 15
Date d'inscription : 17/11/2008
Re: Cryptage Carré de Polybe...
Il manque le sujet de l'exercice (relire la règle de cette section).
Présentation
- C'est très bien d'avoir nommé les fichiers.
- Indentation logique, mais un peu irrégulière (parfois 4, parfois 8...).
- Quelques lignes vides inutiles
- Pour un do-while, c'est :
Codage
/* main.c */
- Avec gcc en mode sévère, la compilation se passe sans avertissement.
- J'apprécie l'usage du préfixe s_ pour nommer les chaines.
- Contrairement aux idées reçues, l'usage systématique d'une constante symbolique n'est pas forcément une bonne chose. En effet, par son caractère 'global' (définie hors de toute fonction), elle peut créer un dépendance mal venue et faire oublier de passer un paramètre 'taille' à une fonction, ce qui peut être désastreux dans certaines applications... Je vois 2 solutions à cette question :
1 - La définition du tableau est le bon endroit pour définir la valeur de la constante
En effet, ce qui compte, c'est que la définition soit unique et placée dans un endroit stratégique.
(pourrait être facilité par l'usage de la macro NELEM())
2 - Mise en place de la stratégie de réduction de la portée des constantes, objets et fonctions :
On peut simuler une définition 'locale' de la macro grâce à une astuce syntaxique peu orthodoxe, mais correcte et efficace :
Dans le même esprit, et s'agissant d'une constante 'entier', on peut utiliser enum :
L'effet n'est pas spectaculaire ici, mais dans d'autres circonstances, il aurait pu révéler des dépendances indésirables...
- Je suis étonné par cette séquence :
Toujours dans le cadre de la politique de réduction de la portée des objets, je suggère de limiter la portée de i au strict minimum :
Par contre, je m'interroge sur le code lui même. Bien que ce ne soit pas très lisible,
(je propose : )
Je suis d'autant plus surpris par ce résultat ...
Ah, j'ai compris ! La condition d'arrêt est sur la chaine saisie ! C'est tordu ! Je suggère que la fonction de cryptage renvoie la longueur de la chaine cryptée et que celle-ci soit utilisée pour l'affichage :
/* polybe.h */
Ici, pas de problèmes, je fais la modification.
/* polybe.c */
- Très bien le #include "polybe.h" en 1er include.
- La chaine ayant été nettoyée, on peut supprimer ceci :
- Attention, ce code n'est pas portable :
Je n'irais pas plus loin pour le moment, car ce problème est à résoudre avant tout.
Voici le code actuel :
Présentation
- C'est très bien d'avoir nommé les fichiers.
- Indentation logique, mais un peu irrégulière (parfois 4, parfois 8...).
- Quelques lignes vides inutiles
- Pour un do-while, c'est :
- Code:
do
{
/* actions */
}
while ();
- Code:
/* guard */
Codage
/* main.c */
- Avec gcc en mode sévère, la compilation se passe sans avertissement.
- J'apprécie l'usage du préfixe s_ pour nommer les chaines.
- Contrairement aux idées reçues, l'usage systématique d'une constante symbolique n'est pas forcément une bonne chose. En effet, par son caractère 'global' (définie hors de toute fonction), elle peut créer un dépendance mal venue et faire oublier de passer un paramètre 'taille' à une fonction, ce qui peut être désastreux dans certaines applications... Je vois 2 solutions à cette question :
1 - La définition du tableau est le bon endroit pour définir la valeur de la constante
En effet, ce qui compte, c'est que la définition soit unique et placée dans un endroit stratégique.
- Code:
char s_phraseACrypter[1000];
char s_phraseCryptee[sizeof s_phraseACrypter];
...
fgets (s_phraseACrypter, sizeof s_phraseACrypter, stdin);
(pourrait être facilité par l'usage de la macro NELEM())
- Code:
#define NELEM(a) (sizeof(a)/sizeof*(a))
...
char s_phraseACrypter[1000];
char s_phraseCryptee[NELEM (s_phraseACrypter)];
...
fgets (s_phraseACrypter, NELEM (s_phraseACrypter), stdin);
2 - Mise en place de la stratégie de réduction de la portée des constantes, objets et fonctions :
On peut simuler une définition 'locale' de la macro grâce à une astuce syntaxique peu orthodoxe, mais correcte et efficace :
- Code:
int main (void)
{
#define MAX 1000
char s_phraseACrypter[MAX];
char s_phraseCryptee[MAX];
...
printf ("Entrez la phrase a crypter:\n");
fgets (s_phraseACrypter, MAX, stdin);
...
return 0;
#undef MAX
}
Dans le même esprit, et s'agissant d'une constante 'entier', on peut utiliser enum :
- Code:
int main (void)
{
enum {MAX = 1000};
char s_phraseACrypter[MAX];
char s_phraseCryptee[MAX];
...
printf ("Entrez la phrase a crypter:\n");
fgets (s_phraseACrypter, MAX, stdin);
...
return 0;
}
L'effet n'est pas spectaculaire ici, mais dans d'autres circonstances, il aurait pu révéler des dépendances indésirables...
- Je suis étonné par cette séquence :
- Code:
fgets (s_phraseACrypter, MAX, stdin);
crypterPolybe (s_phraseACrypter, s_phraseCryptee);
- Code:
fgets (s_phraseACrypter, MAX, stdin);
fclean (s_phraseACrypter, stdin);
crypterPolybe (s_phraseACrypter, s_phraseCryptee);
- Code:
#include <stdio.h>
#include <string.h>
void fclean (char *line, FILE * fp)
{
char *p = strchr (line, '\n');
if (p != NULL)
{
*p = 0;
}
else
{
int c;
while ((c = fgetc (fp)) != '\n' && c != EOF)
{
}
}
}
Toujours dans le cadre de la politique de réduction de la portée des objets, je suggère de limiter la portée de i au strict minimum :
- Code:
int mainj (void)
{
...
{
int i;
for (i = 0; s_phraseACrypter[i]; i++)
{
printf ("%d ", s_phraseCryptee[i]);
}
}
...
return 0;
}
Par contre, je m'interroge sur le code lui même. Bien que ce ne soit pas très lisible,
(je propose : )
- Code:
for (i = 0; s_phraseACrypter[i] != 0; i++)
Je suis d'autant plus surpris par ce résultat ...
- Code:
Entrez la phrase a crypter:
Hello world
Voici la phrase cryptee:
0 15 32 32 35 0 52 35 43 32 14
Process returned 0 (0x0) execution time : 4.204 s
Press any key to continue.
Ah, j'ai compris ! La condition d'arrêt est sur la chaine saisie ! C'est tordu ! Je suggère que la fonction de cryptage renvoie la longueur de la chaine cryptée et que celle-ci soit utilisée pour l'affichage :
- Code:
{
int n = crypterPolybe (s_phraseACrypter, s_phraseCryptee);
printf ("Voici la phrase cryptee:\n");
{
int i;
for (i = 0; i < n; i++)
{
printf ("%d ", s_phraseCryptee[i]);
}
}
printf ("\n");
}
/* polybe.h */
- Code:
int crypterPolybe (char *, char *);
- Code:
int crypterPolybe (char *s_acoder, char *s_codee);
- Code:
int crypterPolybe (char const *s_acoder, char *s_codee);
- Code:
int crypterPolybe (char *s_codee, char const *s_acoder);
Ici, pas de problèmes, je fais la modification.
/* polybe.c */
- Très bien le #include "polybe.h" en 1er include.
- La chaine ayant été nettoyée, on peut supprimer ceci :
- Code:
char *p = strchr (s_phraseACrypter, '\n');
if (p != NULL)
{
*p = 0;
}
- Code:
Entrez la phrase a crypter:
Voici la phrase cryptee:
0
Process returned 0 (0x0) execution time : 1.429 s
Press any key to continue.
- Attention, ce code n'est pas portable :
- Code:
int c = s_phraseACrypter[i] - 'a';
Je n'irais pas plus loin pour le moment, car ce problème est à résoudre avant tout.
Voici le code actuel :
- Code:
/* main.c */
#include "polybe.h"
#include <stdio.h>
#include <string.h>
static void fclean (char *line, FILE * fp)
{
char *p = strchr (line, '\n');
if (p != NULL)
{
*p = 0;
}
else
{
int c;
while ((c = fgetc (fp)) != '\n' && c != EOF)
{
}
}
}
static void afficherCryptee (char const *s_phraseCryptee, int n)
{
int i;
printf ("Voici la phrase cryptee:\n");
for (i = 0; i < n; i++)
{
printf ("%d ", s_phraseCryptee[i]);
}
printf ("\n");
}
int main (void)
{
enum
{ MAX = 1000 };
char s_phraseACrypter[MAX];
char s_phraseCryptee[MAX];
printf ("Entrez la phrase a crypter:\n");
fgets (s_phraseACrypter, MAX, stdin);
fclean (s_phraseACrypter, stdin);
{
int n = crypterPolybe (s_phraseCryptee, s_phraseACrypter);
afficherCryptee (s_phraseCryptee, n);
}
return 0;
}
- Code:
#ifndef H_POLYBE
#define H_POLYBE
/* polybe.h */
int crypterPolybe (char *s_codee, char const *s_acoder);
#endif /* guard */
- Code:
/* polybe.c */
#include "polybe.h"
int crypterPolybe (char *s_phraseCryptee, char const *s_phraseACrypter)
{
int i = 0;
do
{
int c = s_phraseACrypter[i] - 'a';
if (s_phraseACrypter[i] >= 'a' && s_phraseACrypter[i] <= 'v')
{
s_phraseCryptee[i] = c + 11 + 5 * (c / 5);
}
else if (s_phraseACrypter[i] >= 'w' && s_phraseACrypter[i] <= 'z')
{
c--;
s_phraseCryptee[i] = c + 11 + 5 * (c / 5);
}
else
{
s_phraseCryptee[i] = 0;
}
i++;
}
while (s_phraseACrypter[i]);
return i;
}
Bien reçu !
Un grand merci à toi !
Il n'y avait pas d'énoncé particulier, c'est pour mes TPE de 1ère SI (sujet: cryptographie, problématique à trouver). Il s'agissait juste de crypter avec le carré de Polybe, avec un code le mieux possible. Donc j'applique tes modifications et celles conseillées par d'autres personnes, et je posterai mon nouveau code. A savoir que je posterai le cryptage avec césar. Et si tu pouvait m'aider pour la fonction de décryptage, je n'y arrive pas.
J'ai quelques questions:
1)
Je ne comprend pas le else... tu pourrais m'expliquer?
2) Toutes les nouvelles fonctions ne devraient-elles pas être déclarées dans polybe.h ?
3)
A quoi servent les {} ? Pour quelle fonction ?
4)
Je ne comprend pas ces arguments peux-tu m'expliquer ?
Au niveau de l'amélioration:
- la gestion des majuscules, il suffit de créer une boucle avec toupper() ?
- la gestion des accents: est il possible de transformer un "é" par exemple en "e" (le carré de Polybe ne gérant pas lui-même les accents)... ou de faire une gestion des exceptions ?
- gestion des espaces :les 0 sont-ils remplaçables par un espace? Car x == " " par exemple n'affiche pas un espace...
merci d'avance !
Il n'y avait pas d'énoncé particulier, c'est pour mes TPE de 1ère SI (sujet: cryptographie, problématique à trouver). Il s'agissait juste de crypter avec le carré de Polybe, avec un code le mieux possible. Donc j'applique tes modifications et celles conseillées par d'autres personnes, et je posterai mon nouveau code. A savoir que je posterai le cryptage avec césar. Et si tu pouvait m'aider pour la fonction de décryptage, je n'y arrive pas.
J'ai quelques questions:
1)
- Code:
#include <stdio.h>
#include <string.h>
void fclean (char *line, FILE * fp)
{
char *p = strchr (line, '\n');
if (p != NULL)
{
*p = 0;
}
else
{
int c;
while ((c = fgetc (fp)) != '\n' && c != EOF)
{
}
}
}
Je ne comprend pas le else... tu pourrais m'expliquer?
2) Toutes les nouvelles fonctions ne devraient-elles pas être déclarées dans polybe.h ?
3)
- Code:
fclean (s_phraseACrypter, stdin);
{
int n = crypterPolybe (s_phraseCryptee, s_phraseACrypter);
afficherCryptee (s_phraseCryptee, n);
}
A quoi servent les {} ? Pour quelle fonction ?
4)
- Code:
static void afficherCryptee (char const *s_phraseCryptee, int n)
Je ne comprend pas ces arguments peux-tu m'expliquer ?
Au niveau de l'amélioration:
- la gestion des majuscules, il suffit de créer une boucle avec toupper() ?
- la gestion des accents: est il possible de transformer un "é" par exemple en "e" (le carré de Polybe ne gérant pas lui-même les accents)... ou de faire une gestion des exceptions ?
- gestion des espaces :les 0 sont-ils remplaçables par un espace? Car x == " " par exemple n'affiche pas un espace...
merci d'avance !
azerty- Bavard
- Messages : 15
Date d'inscription : 17/11/2008
Re: Cryptage Carré de Polybe...
http://mapage.noos.fr/emdel/notes.htm#saisieazerty a écrit:Je ne comprend pas le else... tu pourrais m'expliquer?
- Code:
#include <stdio.h>
#include <string.h>
void fclean (char *line, FILE * fp)
{
char *p = strchr (line, '\n');
if (p != NULL)
{
*p = 0;
}
else
{
int c;
while ((c = fgetc (fp)) != '\n' && c != EOF)
{
}
}
}
http://mapage.noos.fr/emdel/notes.htm#fichiers
Ca dépend si elles ont publiques ou non (static)...2) Toutes les nouvelles fonctions ne devraient-elles pas être déclarées dans polybe.h ?
en C90, une variable doit être définie au début d'un bloc. Aucun rapport avec une fonction.
3)
- Code:
fclean (s_phraseACrypter, stdin);
{
int n = crypterPolybe (s_phraseCryptee, s_phraseACrypter);
afficherCryptee (s_phraseCryptee, n);
}
A quoi servent les {} ? Pour quelle fonction ?
[quote]
4)
- Code:
static void afficherCryptee (char const *s_phraseCryptee, int n)
[/quote]
s_phraseCryptee : pointeur sur un char non modifiable. C'est l'adresse du premier élément du tableau de char qui contient la chaine cryptée.
n : entier de type int. C'est le nombre d'éléments du tableau de char qui contient la chaine cryptée.
Je ne comprend pas ces arguments peux-tu m'expliquer ?
Par exemple, ou l'ajouter dans une boucle existante (éviter de multiplier les boucles quand une suffit).Au niveau de l'amélioration:
- la gestion des majuscules, il suffit de créer une boucle avec toupper() ?
Pas de manière portable, car le langage C ne connait pas 'é'. Il faut le faire à la main.- la gestion des accents: est il possible de transformer un "é" par exemple en "e"
J'ai fait ça ...
http://mapage.noos.fr/emdel/clib.htm
Module ASCII (nom mal choisi, mais c'est comme ça...)
Quels 0 ?- gestion des espaces :les 0 sont-ils remplaçables par un espace?
une expression ne peut pas afficher quoi que ce soit. Soit plus précis, je ne comprends pas ta demande.Car x == " " par exemple n'affiche pas un espace...
Espaces
En gros quand l'utilisateur rentre "je programme" j'aimerai que le résultat soit "4421 3456..." (heu j'ai mis les nombres au hasard), l'espace étant présent dans le phrase codée...
azerty- Bavard
- Messages : 15
Date d'inscription : 17/11/2008
Re: Cryptage Carré de Polybe...
Ce que tu veux dire, en clair, c'est que la structure de la phrase doit être préservée (espaces, ponctuation, fins de ligne ?)azerty a écrit:En gros quand l'utilisateur rentre "je programme" j'aimerai que le résultat soit "4421 3456..." (heu j'ai mis les nombres au hasard), l'espace étant présent dans le phrase codée...
codage
Oui. au moins les espaces, la ponctuation c'est moins important (dans l'idéal il faudrait carrément supprimer la ponctuation... je pense inclure cela dans une autre fonction static, mais dois-je gérer chaque type de ponctuation à la main ?).
azerty- Bavard
- Messages : 15
Date d'inscription : 17/11/2008
Re: Cryptage Carré de Polybe...
Il faut différencier le traitement du caractère en fonction de son appartenance. Tu peux utiliser ispunct(), par exemple.azerty a écrit:Oui. au moins les espaces, la ponctuation c'est moins important (dans l'idéal il faudrait carrément supprimer la ponctuation... je pense inclure cela dans une autre fonction static, mais dois-je gérer chaque type de ponctuation à la main ?).
- Code:
#nbclude <ctype.h>
{
for(...)
{
c = tab[i];
if (ispunct(c))
{
...
}
else
{
...
}
ok
Merci !
Où puis-je trouver de la documentation en français sur ces deux fonctions ?
Où puis-je trouver de la documentation en français sur ces deux fonctions ?
azerty- Bavard
- Messages : 15
Date d'inscription : 17/11/2008
Re: Cryptage Carré de Polybe...
Dans ton livre de C ?azerty a écrit:Merci !
Où puis-je trouver de la documentation en français sur ces deux fonctions ?
Sinon : http://man.developpez.com/man3/ C'est orienté Linux, mais dans l'ensemble, les informations sont correctes.
Au fait, pourquoi "en français" ? Pour avancer dans ce métier, il faut savoir bien lire l'anglais.
Francais?
Oui... mais je met 2 fois plus de temps avec une doc en anglais, ce qui ne me dérange pas habituellement, mais vu que c'est pressé...
azerty- Bavard
- Messages : 15
Date d'inscription : 17/11/2008
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum
|
|