Code César : chiffré et déchiffrer un message en C

Fermé
Shadow_74 Messages postés 20 Date d'inscription jeudi 6 avril 2023 Statut Membre Dernière intervention 10 avril 2023 - Modifié le 11 avril 2023 à 16:35
[Dal] Messages postés 6187 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 14 juin 2024 - 14 avril 2023 à 11:23

Bonjour, s'il vous plaît quelqu'un peut m'aider ici, 

Ecrire un programme C qui permet de coder un message à l’aide du code Césaravec n’importe quel texte saisie au clavier.

#include <string.h>
int main()
{
    char message[] = {"JESUS EST SEIGNEUR"};
    char msg_crypte[100];
    long i;
    for (i =0;i<strlen(message); i++)
        ;
    {
    msg_crypte[i] = message[i] + 3;
    }
    printf("%s \n", message);
    printf("%s \n", msg_crypte);
    return 0;
}


Android / Chrome 107.0.5304.105


A voir également:

32 réponses

Shadow_74 Messages postés 20 Date d'inscription jeudi 6 avril 2023 Statut Membre Dernière intervention 10 avril 2023 1
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


0
Whismeril Messages postés 19055 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 12 juin 2024 914
8 avril 2023 à 18:51

oui c'est ça

0
Whismeril Messages postés 19055 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 12 juin 2024 914
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?


0
Shadow_74 Messages postés 20 Date d'inscription jeudi 6 avril 2023 Statut Membre Dernière intervention 10 avril 2023 1
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 


0
Whismeril Messages postés 19055 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 12 juin 2024 914
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 ?


0
Shadow_74 Messages postés 20 Date d'inscription jeudi 6 avril 2023 Statut Membre Dernière intervention 10 avril 2023 1
9 avril 2023 à 21:14

Je n'arrive pas à trouver la réponse sur cette question 

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Whismeril Messages postés 19055 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 12 juin 2024 914
9 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?


0
Shadow_74 Messages postés 20 Date d'inscription jeudi 6 avril 2023 Statut Membre Dernière intervention 10 avril 2023 1
10 avril 2023 à 06:46

Si il y'a moyen, il y'a la clé de 3 qui est la 

0

@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?

0
Whismeril Messages postés 19055 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 12 juin 2024 914
10 avril 2023 à 08:09

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

0
Whismeril Messages postés 19055 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 12 juin 2024 914
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 ?


0
Shadow_74 Messages postés 20 Date d'inscription jeudi 6 avril 2023 Statut Membre Dernière intervention 10 avril 2023 1
10 avril 2023 à 18:48

Oui je peux le faire 

0
Whismeril Messages postés 19055 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 12 juin 2024 914 > Shadow_74 Messages postés 20 Date d'inscription jeudi 6 avril 2023 Statut Membre Dernière intervention 10 avril 2023
10 avril 2023 à 19:08

Et qu'attends tu?

0
PierrotLeFou
10 avril 2023 à 18:15

J'ai déjjà donné des indices au début sur ce point.

0
Whismeril Messages postés 19055 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 12 juin 2024 914
10 avril 2023 à 19:16

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?

0
PierrotLeFou
11 avril 2023 à 01:08

Shadow_74 a écrit:
Oui je peux le faire
Whismeril a écrit:
Et qu'attends tu?
 
Bon, j'attend également.

0
[Dal] Messages postés 6187 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 14 juin 2024 1 088
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);

https://cplusplus.com/reference/cstdio/scanf/

0
[Dal] Messages postés 6187 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 14 juin 2024 1 088
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.

0
Bernetta Messages postés 2 Date d'inscription mercredi 12 avril 2023 Statut Membre Dernière intervention 18 avril 2023
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;
}
}
```

0
Whismeril Messages postés 19055 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 12 juin 2024 914
12 avril 2023 à 15:40

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

0
[Dal] Messages postés 6187 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 14 juin 2024 1 088
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".

0