Code César : chiffré et déchiffrer un message en C
Fermé[Dal] Messages postés 6200 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 7 janvier 2025 - 14 avril 2023 à 11:23
- Code césar déchiffrer
- Code asci - Guide
- Code puk bloqué - Guide
- Code telephone oublié - Guide
- Code activation windows 10 - Guide
- Code gta 4 ps4 - Guide
32 réponses
8 avril 2023 à 18:48
Merci Pour la correction, je pense que j'ai encore beaucoup a apprendre, concernant déchiffrer le message chiffré la c'est pas trop difficile je vais juste faire l'inverse de ce que j'ai fait au premier code
Modifié le 9 avril 2023 à 08:52
OK.
Maintenant, il reste des points qu'avait évoqués [Dal].
A l'origine le chiffre de Cesar n'utilisait que des lettres.
Les espaces restaient des espaces, je ne sais pas si la ponctuation existait, mais si oui, elle devait être ignorée.
Mais surtout avec un décalage de 3, "z" donnait "c", l'alphabet était considéré comme un anneau, arrivé à la fin, on repart au début. C'est ce qu'on appelle la permutation circulaire de l'alphabet.
Dans ta version, tous les caractères sont chiffrés ce qui est le cas des chiffrages modernes, laisser les espaces et la ponctuation donne beaucoup trop d'indications pour décrypter le message, et "z" donne ")".
Mais tu coup, ton code n'est pas vraiment le chiffre de César.
Dans un premier, en partant du principe que le texte est toujours tout en minuscules, comment résoudrais tu ce point?
9 avril 2023 à 09:23
Ce code peut prendre le minuscule ainsi que majuscule mais le ponctuation ne marche pas, x,y,z ne fait pas le tour pour donner a,b,c , l'espace ça donne #. Du coup je ne sais pas trop ce qu'il faut ajouter
9 avril 2023 à 10:17
Si si, ton code chiffres bien tous les caractères, y compris la ponctuation
L'idée serait donc de ne traiter que les caractères de 'a' à 'z'.
Comment pourrais-tu t'y prendre ?
9 avril 2023 à 21:14
Je n'arrive pas à trouver la réponse sur cette question
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question9 avril 2023 à 23:41
Dans cette boucle
for (i = 0; i < strlen(message); i++) { msg_chiffre[i] = message[i] + 3; }
n'y a t il pas moyen de choisir d'appliquer le décalage ou pas selon le caractère d'origine?
10 avril 2023 à 06:46
Si il y'a moyen, il y'a la clé de 3 qui est la
@Whismeril:
Question de terminologie, puisque tu as abordé le sujet:
Comment appellerait-on une "méthode" de transformation d'un message si la clé est cachée dans le message transformé et si on ne connait pas cette méthode.
Je donne un exemple simple pour les lettres:
Je définit un cycle de longueur N.
Je décale le premier caractère d'une distance A
Je décale le second caractère d'une distance B.
etc. jusqu'à N
Et je recommence en décalant le N+1 ième de A, et ainsi de suite.
Si le premier caractère donne la valeur de N en décalant A.
Par exemple, si j'ai un cycle de 3, le premier caractère sera D
Les 3 caractères suivant seront les valeurs de A, B, etc. comme décalage
Par exemple:
DEBJmessage_transformé
veut dire que j'ai un cycle de 3, que le premier a été décalé de 4, le second de 1, et le troisième de 9, le suivant de 4, etc.
Est-ce que cette méthode résiste à une analyse fréquencielle?
Bonjour Pierrot,
Je ne suis pas spécialiste de la crypto. Mais dans ce que tu décris, le déchiffreur doit connaître la clé de départ et qu'elle s'applique jusqu'à trouver la nouvelle clé. Et le "casseur" doit chercher à comprendre ça....
En ce qui me concerne, j'essaie juste de faire faire son exercice à Shadow, avec précision, mais sans déborder du cadre
10 avril 2023 à 08:11
Shadow.
Saurais tu réécrire le bloc exécuté par la boucle de façon à ce que si le caractère est une lettre on applique un décalage et si ce n'est pas une lettre, on le copie sans décalage ?
10 avril 2023 à 18:48
Oui je peux le faire
10 avril 2023 à 19:08
Et qu'attends tu?
J'ai déjjà donné des indices au début sur ce point.
Oui Pierrot quand on en était à résoudre le problème du for, tu parlais déjà de distinguer les minuscules des majuscules, depuis tu nous a parlé d'une autre méthode de chiffrement.
Et maintenant qu'on essaye de ne chiffrer que les minuscules, tu reviens avec les majuscules.
Mais avant, on va essayer de gérer la permutation circulaire, qu'en penses-tu?
Shadow_74 a écrit:
Oui je peux le faire
Whismeril a écrit:
Et qu'attends tu?
Bon, j'attend également.
Modifié le 11 avril 2023 à 15:47
Désolé, je n'ai pas pu me connecter ces derniers jours.
1.
Un petit coup de pouce, pour débloquer Shadow_74.
Pierrot avait effectivement donné des indications sur "si le caractère est une lettre on applique un décalage et si ce n'est pas une lettre, on le copie sans décalage" en évoquant la fonction isalpha() utilisable en faisant un #include <ctype.h>
https://cplusplus.com/reference/cctype/isalpha/
Dans cette documentation, il y a un code d'exemple qui montre comme vérifier dans une boucle for si les char qui composent une chaîne sont des caractères alphabétiques ou pas, en affichant quelque chose selon le cas.
Cela devrait inspirer Shadow_74 :-)
2.
C'est peut-être un peu avancé pour Shadow_74, mais tant pis.
La vérité c'est que, en C, ce n'est vraiment pas évident de gérer une saisie d'un utilisateur correctement.
S'agissant de gets(), pour prendre une chaîne avec des espaces, c'est une fonction très simple pour un débutant, mais n'est plus dans le standard du C depuis 2011 en raison de sa dangerosité (les compilateurs récents ne l'implémentent plus), car elle ne permet pas de limiter la taille de la saisie. Dans la même famille, c'est fgets() qu'il faudrait utiliser, qui permet de délimiter le nombre maximal de char stockés à partir d'un flux, ce que ne permet pas gets() :
/* récupération d'une ligne */ char message[10000]; printf("entrez le message (9999 char maximum) : "); fgets(message, 10000, stdin); /* retrait du retour à la ligne */ char * pos; if ((pos=strchr(Name, '\n')) != NULL) *pos = '\0'; else printf("Ligne trop longue, je ne traite que les 9999 premiers chars\n");
https://cplusplus.com/reference/cstdio/fgets/
Ci-dessus, j'ai mis du code montrant aussi comment retirer le retour à la ligne car, autrement, fgets() (ou même gets()) incluent le retour à la ligne tapé par l'utilisateur en fin de chaîne, et il est probable qu'on n'en veuille pas dans le cas de Shadow_74.
On peut aussi saisir une chaîne avec des espaces avec scanf() en limitant également le nombre de chars acceptés, à condition d'utiliser les bons spécificateurs de format. Ce qui a l'avantage de ne pas encombrer la chaîne récupérée du caractère de retour à la ligne.
/* récupération d'une ligne */ char message[10000]; printf("entrez le message (9999 char maximum) : "); scanf("%9999[^\n]", message);
Modifié le 12 avril 2023 à 12:34
Salut Shadow_74,
Si tu as vu les fonctions à ton stade d'apprentissage du C, voici une méthodologie te permettant de mettre au point progressivement ton code, en mettant le coeur du comportement de chiffrement souhaité dans une fonction testable, et en écrivant des tests nécessaires pour couvrir les différents de cas de figure.
#include <stdio.h> #include <string.h> #include <ctype.h> #include <stdbool.h> #include <assert.h> char caesar_crypt(char c, int shift) { /* TODO */ } bool test_caesar_crypt(void) { /* décalage simple majuscules */ assert( caesar_crypt('X', 1) == 'Y' ); assert( caesar_crypt('X', 2) == 'Z' ); /* décalage circulaire majuscules */ assert( caesar_crypt('X', 3) == 'A' ); assert( caesar_crypt('Y', 3) == 'B' ); assert( caesar_crypt('Z', 3) == 'C' ); /* décalage simple minuscules */ assert( caesar_crypt('x', 1) == 'y' ); assert( caesar_crypt('x', 2) == 'z' ); /* décalage circulaire minuscules */ assert( caesar_crypt('x', 3) == 'a' ); assert( caesar_crypt('y', 3) == 'b' ); assert( caesar_crypt('z', 3) == 'c' ); /* caractères autres que des lettres ignorés */ assert( caesar_crypt(' ', 3) == ' ' ); assert( caesar_crypt(',', 3) == ',' ); assert( caesar_crypt('.', 3) == '.' ); /* tous les tests ont passé */ printf("Tous les tests dans test_caesar_crypt() ont passé\n"); return true; } int main(void) { assert(test_caesar_crypt()); /* une fois que tous les tests ont passé * la ligne ci-dessus peut être supprimée et * le code ci-dessous décommenté */ // char message[100]; // char msg_crypte[100]; // // printf("entrez le message (99 char maximum) : "); // scanf("%99[^\n]", message); // // size_t msg_len = strlen(message); // for (size_t i = 0; i < msg_len; i++) // msg_crypte[i] = caesar_crypt(message[i], 3); // // printf("Message d'origine : %s\n", message); // printf("Message chiffré : %s\n", msg_crypte); /* TODO: faire la fonction de déchiffrement */ return 0; }
Lorsqu'un test échoue, assert() va interrompre l'exécution du programme et t'indiquer sur quelle ligne du programme se trouve le test qui a échoué.
Fait passer ces tests un par un.
Une fois que tous les tests passent, tu pourras considérer que la fonction de chiffrement est "au point" et tu peux l'utiliser dans la boucle de ton code.
Chez moi, cette fonction char caesar_crypt(char c, int shift) fait moins de 10 lignes et elle utilise les fonctions isalpha() et isupper() / islower() dont Pierrot avait recommandé l'utilisation.
Tu pourras utiliser une méthode similaire pour mettre au point ta fonction de déchiffrement.
12 avril 2023 à 12:38
Hey look at this code :
```
#include
#include
void caesar_cipher(char *message, int key);
int main() {
char message[100];
int key;
printf("Enter a message to encrypt: ");
fgets(message, sizeof(message), stdin);
printf("Enter encryption key: ");
scanf("%d", &key);
caesar_cipher(message, key);
printf("Encrypted message: %s\n", message);
return 0;
}
void caesar_cipher(char *message, int key) {
int i;
char ch;
for(i = 0; i < strlen(message); i++) {
ch = message[i];
if(ch >= 'a' && ch <= 'z') {
ch = (ch + key - 'a') % 26 + 'a';
}
else if(ch >= 'A' && ch <= 'Z') {
ch = (ch + key - 'A') % 26 + 'A';
}
message[i] = ch;
}
}
```
Bonjour Bernetta.
d'abord ici on parle français.
Ensuite, on ne donne pas de solution toute faite, on essaye de faire réfléchir le demandeur pour qu'il arrive à sa propre solution.
Et enfin, on présente le code que l'on poste de la façon décrite ici https://codes-sources.commentcamarche.net/faq/11288-poster-un-extrait-de-code
Modifié le 14 avril 2023 à 11:24
Salut Shadow_74,
As-tu pu terminer ton devoir avec les indications qui t'ont été données ?
Si tu tu n'as plus de questions, tu peux mettre ce fil en "Résolu".
8 avril 2023 à 18:51
oui c'est ça