Commit 17ba8f8f9b0b9513fd9513135aec09215d29bb64

Authored by tevrard
0 parents

Ajout du code

Melodico 0 → 100755
No preview for this file type
TheoEvrard_CR_TIM.pdf 0 → 100644
No preview for this file type
imposteurs.ppm 0 → 100644
No preview for this file type
inc/automatos.h 0 → 100644
  1 +++ a/inc/automatos.h
... ... @@ -0,0 +1,7 @@
  1 +int Parity_check(Image **I, int algo_tab[], int i, int j);
  2 +void Parity_encode(Image **I, unsigned char *msg);
  3 +void Parity_decode(Image **I, unsigned char *msg);
  4 +void Change_LSB(unsigned char *x);
  5 +void GetOneChar(unsigned char x, unsigned char *a, int i);
  6 +void bit_in_tab(unsigned char *byte, int tab[]);
  7 +uint8_t Get_msg_size(Image **I);
0 8 \ No newline at end of file
... ...
inc/stegano.h 0 → 100644
  1 +++ a/inc/stegano.h
... ... @@ -0,0 +1,27 @@
  1 +/* Structures permettant le stockage de l'image */
  2 +typedef struct Pix_rgb
  3 +{
  4 + unsigned char red;
  5 + unsigned char green;
  6 + unsigned char blue;
  7 +} Pix_rgb;
  8 +
  9 +typedef struct Image
  10 +{
  11 + int width;
  12 + int height;
  13 + Pix_rgb** Mat_data;
  14 +} Image;
  15 +
  16 +
  17 +
  18 +/* Prototypes */
  19 +void NouvelleImage(int width, int height, Image** I);
  20 +void free_image(Image** I);
  21 +void read_header(FILE * im_file, int *width, int *height);
  22 +int sauvegarde_ppm(char* fichier, Image** I);
  23 +int chargement_ppm(char *image_name, Image** I);
  24 +void GetPartChar(unsigned char x, unsigned char *a, int i);
  25 +void SetPartChar(unsigned char *x, unsigned char a, int i);
  26 +void LSB_hide(Image **I, unsigned char *msg, int encode, int vigenere, unsigned char *cle);
  27 +void Next_pixel(Image **I, int *current_pos, int *i, int *j, int vigenere, unsigned char *cle);
0 28 \ No newline at end of file
... ...
inc/vigenere.h 0 → 100644
  1 +++ a/inc/vigenere.h
... ... @@ -0,0 +1,3 @@
  1 +#define TAILLE_MAX 10000
  2 +
  3 +void vigenere(unsigned char *message, unsigned char *cle, int tailleCle, int encode);
... ...
makefile 0 → 100644
  1 +++ a/makefile
... ... @@ -0,0 +1,13 @@
  1 +SOURCES = ./src/main.c ./src/automatos.c ./src/vigenere.c ./src/stegano.c
  2 +OBJETS = $(SOURCES:.c=.o)
  3 +EXECUTABLE = Melodico
  4 +CFLAGS += -Wall -Wextra
  5 +
  6 +all: $(EXECUTABLE)
  7 +
  8 +$(EXECUTABLE): $(OBJETS)
  9 + $(CC) -o $@ $^ #$(BIBLIOTHEQUES)
  10 + rm -rf ./src/*.o
  11 +
  12 +clean:
  13 + rm -rf $(EXECUTABLE) ./src/*.o
... ...
src/automatos.c 0 → 100644
  1 +++ a/src/automatos.c
... ... @@ -0,0 +1,169 @@
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <string.h>
  4 +#include <stdint.h>
  5 +#include "../inc/stegano.h"
  6 +#include "../inc/automatos.h"
  7 +
  8 +
  9 +/* Inverse le LSB d'un unsigne char *x passé en paramètre
  10 + ex : 01001011 -> 01001010 */
  11 +void Change_LSB(unsigned char *x) {
  12 +
  13 + unsigned char mask = 0x01; //0b00000001
  14 + unsigned char tmp;
  15 +
  16 + tmp = *x & mask;
  17 + tmp = ~tmp & 0x01;
  18 + *x = (*x & 0xFE) | tmp;
  19 +}
  20 +
  21 +
  22 +/* Copie le LSB de x pour le stocker à la ie position de a */
  23 +void GetOneChar(unsigned char x, unsigned char *a, int i) {
  24 +
  25 + unsigned char mask = 0x01; //0b00000001
  26 + *a += (x & mask) << (7-i);
  27 +}
  28 +
  29 +
  30 +/* Determine la parité du voisinage d'un pixel (de coordonnées int i, int j)
  31 + La règle à utiliser est passée en paramètre via int algo_tab[] */
  32 +int Parity_check(Image **I, int algo_tab[], int i, int j) {
  33 +
  34 + /* Pixels à considérer pour la parité */
  35 + int vois[9][2] = { { i , j } , { i , j+1 } , { i+1 , j+1 },
  36 + { i+1 , j } , { i+1 , j-1 } , { i , j-1 },
  37 + { i-1 , j-1 } , { i-1 , j } , { i-1 , j+1 } };
  38 + int parity = 0;
  39 + int h = (*I)->height;
  40 + int w = (*I)->width;
  41 +
  42 + /* Evaluation et stockage de la parité de chaque pixel voisin */
  43 + for (int k=0; k < 8; k++) {
  44 +
  45 + /* Considère ou non le voisin en fonction de l'algorithme de parité à appliquer */
  46 + if (algo_tab[k] == 1) {
  47 + /* Verifie les dépassements de tableau */
  48 + if (vois[k+1][0] >= 0 && vois[k+1][0] < h && vois[k+1][1] >= 0 && vois[k+1][1] < w) {
  49 + // Recupère le LSB du voisin (soit 1 si impair, soit 0 si pair)
  50 + parity += ((*I)->Mat_data[vois[k+1][0]][vois[k+1][1]].blue) % 2; }
  51 + }
  52 + }
  53 + // Ajoute la parité du pixel central lui même
  54 + parity += (*I)->Mat_data[i][j].blue % 2;
  55 + // Determine la parité globale du voisinage (0 si pair, 1 si impair)
  56 + return (parity % 2);
  57 +}
  58 +
  59 +
  60 +/* Stocke les valeurs des 8 bits d'un octets 'byte' dans un int[8] passé en paramètre*/
  61 +void bit_in_tab(unsigned char *byte, int tab[]) {
  62 + for(int k=7; k>=0; k--) {
  63 + tab[k] = *byte % 2;
  64 + *byte = *byte / 2;
  65 + }
  66 +}
  67 +
  68 +
  69 +/* Cache un message de N bit, bit à bit, dans N pixel, en modifiant ou non la parité du voisinage de chaque pixel
  70 + Au terme de la fonction, le voisinage d'un pixel est impair lorsqu'un 1 est caché
  71 + le voisinage d'un pixel est pair lorsqu'un 0 est caché */
  72 +void Parity_encode(Image **I, unsigned char *msg) {
  73 +
  74 + /* Determination de l'algorithme de parité */
  75 + int algo_tab[8];
  76 + unsigned char algo_byte = (*I)->Mat_data[4][4].red;
  77 + bit_in_tab(&algo_byte, algo_tab);
  78 +
  79 + /* variables concernant le message à cacher */
  80 + uint8_t current_byte = 0;
  81 + int hide_byte[8];
  82 + int bit = 0;
  83 + bit_in_tab(&msg[current_byte], hide_byte);
  84 +
  85 + /* Parcours de la matrice */
  86 + int h = (*I)->height;
  87 + int w = (*I)->width;
  88 + int parity = 0;
  89 + int breaking = 0;
  90 +
  91 + for (int i = 0; i < h; i+=2) {
  92 + for (int j = 0; j < w; j+=2) {
  93 +
  94 + /* Calcul de la parité des voisins*/
  95 + parity = Parity_check(I, algo_tab, i, j);
  96 +
  97 + /* Dissimulation du message en fonction de la parité */
  98 + if ((parity == 1) && (hide_byte[bit] == 0)) {
  99 + Change_LSB(&((*I)->Mat_data[i][j].blue));
  100 + }
  101 + else if ((parity == 0) && (hide_byte[bit] == 1)) {
  102 + Change_LSB(&((*I)->Mat_data[i][j].blue));
  103 + }
  104 + bit += 1;
  105 +
  106 + // Fin de message
  107 + if (bit == 8 && breaking == 1) return;
  108 +
  109 + // Fin de caractère
  110 + if (bit == 8) {
  111 + current_byte ++;
  112 + if (msg[current_byte] == '\0') breaking = 1; //Dernier caractère
  113 + bit_in_tab(&msg[current_byte], hide_byte); //Chargement des 8 bits d'un caractère (msg[current_byte]) au sein d'un int[8] (hide_byte)
  114 + bit = 0;
  115 + }
  116 + }
  117 + }
  118 + return;
  119 +}
  120 +
  121 +
  122 +/*
  123 +Table de verité pour l'encodage :
  124 +H = bit à cacher
  125 +R = bit de poids faible du pixel central
  126 +Paire et impaire = parités des voisins du pixel central(dépend de l'algo)
  127 +
  128 +| | H = 0 | H = 1 |
  129 +|----------------------------------|
  130 +| Impaire| change R | Nochange R|
  131 +|----------------------------------|
  132 +| Paire | Nochange R | change R |
  133 +
  134 +*/
  135 +
  136 +
  137 +/* Extrait un potentiel message caché au sein d'une image ppm (stockée préalablement dans une matrice 2D) */
  138 +void Parity_decode(Image **I, unsigned char *msg) {
  139 +
  140 + /* Determination de l'algorithme de parité */
  141 + int algo_tab[8];
  142 + unsigned char algo_byte = (*I)->Mat_data[4][4].red;
  143 + bit_in_tab(&algo_byte, algo_tab);
  144 +
  145 + uint8_t l = 0;
  146 + int bit = 0;
  147 +
  148 + /* Parcours de la matrice */
  149 + int h = (*I)->height;
  150 + int w = (*I)->width;
  151 + int parity = 0;
  152 + for (int i = 0; i < h; i+=2) {
  153 + for (int j = 0; j < w; j+=2) {
  154 +
  155 + // parity == 0 (pair) -> le caractère caché est un 0
  156 + // parity == 1 (impair) -> le caractère caché est un 1
  157 + parity = Parity_check(I, algo_tab, i, j);
  158 + GetOneChar(parity, &msg[l], bit);
  159 + bit ++;
  160 +
  161 + //fin de caractère ou de message
  162 + if (bit == 8) {
  163 + if (msg[l] == '\0') return;
  164 + l ++;
  165 + bit = 0;
  166 + }
  167 + }
  168 + }
  169 +}
... ...
src/main.c 0 → 100644
  1 +++ a/src/main.c
... ... @@ -0,0 +1,132 @@
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <string.h>
  4 +#include <stdint.h>
  5 +#include "../inc/stegano.h"
  6 +#include "../inc/automatos.h"
  7 +#include "../inc/vigenere.h"
  8 +
  9 +
  10 +void help() {
  11 +
  12 + printf("\nHow to use this program :\n");
  13 + printf("Hide message into img :\n");
  14 + printf(" ./tp_tim -e -lsb <image.ppm> \n");
  15 + printf(" -par <image.ppm> \n");
  16 + printf("You can crypt your message with -Vigenere at the end of the command\n\n");
  17 +
  18 + printf("Recover message into img :\n");
  19 + printf(" ./tp_tim -d -lsb <image.ppm> \n");
  20 + printf(" -par <image.ppm> \n");
  21 + printf("You must specify -Vigenere at the end of the command if a cypher text is hiding into the image\n\n");
  22 +
  23 + printf("\nEXAMPLES : \n");
  24 + printf("./tp_tim -e -lsb chaton.ppm -Vigenere\n");
  25 + printf("./tp_tim -d -lsb chaton_enc.ppm -Vigenere\n");
  26 +
  27 + printf("\nNOTES :\n");
  28 + printf("Lors de la dissimulation d'un message, l'image qui en résulte sera sauvegardee sous le nom de 'encrypt.ppm'\n");
  29 +
  30 +}
  31 +
  32 +/* Permet de vider le buffer */
  33 +void clean_stdin(void) {
  34 +
  35 + int c;
  36 + do {
  37 + c = getchar();
  38 + } while (c != '\n');
  39 +}
  40 +
  41 +int main(int argc, char *argv[])
  42 +{
  43 + int vig = 0;
  44 + unsigned char *cle = NULL;
  45 + if (argc > 3) {
  46 +
  47 + Image *I;
  48 + if (chargement_ppm(argv[3], &I) == -1) return -1;
  49 + printf("Chargement OK\n");
  50 + uint8_t max_size = (((I->width)/2) * ((I->height)/2) / 8);
  51 +
  52 +
  53 + /* ENCODE */
  54 + if(strcmp(argv[1], "-e") == 0) {
  55 +
  56 + /* Recuperation du message à cacher */
  57 + unsigned char *msg_s = malloc(max_size);
  58 + printf("Message a cacher (taille max = %d): ", max_size);
  59 + fgets((char * restrict)msg_s, max_size, stdin);
  60 +
  61 + /* Vidage du buffer si msg > max_size */
  62 + if (strlen((const char *)msg_s) >= max_size-1.0) clean_stdin();
  63 +
  64 + /* CHIFFREMENT AVEC VIGENERE */
  65 + if (argc == 5) {
  66 + vig = 1;
  67 + printf("plaintext : %s\n", msg_s);
  68 +
  69 + cle = malloc(max_size);
  70 + memset( cle, 0, max_size);
  71 + printf("Cle vigenere : ");
  72 + fgets((char * restrict)cle, max_size, stdin);
  73 + vigenere(msg_s, cle, strlen((const char *)cle), 1);
  74 +
  75 + printf("cypher : %s\n", msg_s);
  76 + }
  77 +
  78 + /* LSB Methode ou PARITÉ Methode ou ERREUR */
  79 + if(strcmp(argv[2], "-lsb") == 0) LSB_hide(&I, msg_s, 1, vig, cle);
  80 + else if (strcmp(argv[2], "-par") == 0) Parity_encode(&I, msg_s);
  81 + else {
  82 + printf("wrong option [ MUST BE -par OR -lsb ]\n");
  83 + }
  84 +
  85 + sauvegarde_ppm("encrypt.ppm", &I);
  86 +
  87 + free(msg_s);
  88 + if (argc == 5) free(cle);
  89 + }
  90 +
  91 +
  92 + /* DECODE */
  93 + else if(strcmp(argv[1], "-d") == 0) {
  94 +
  95 + unsigned char *buff = malloc(max_size);
  96 + memset( buff, 0, max_size);
  97 +
  98 + /* CHIFFREMENT AVEC VIGENERE */
  99 + if (argc == 5) {
  100 + vig = 1;
  101 + cle = malloc(max_size);
  102 + memset( cle, 0, max_size);
  103 + printf("Cle vigenere : ");
  104 + fgets((char * restrict)cle, max_size, stdin);
  105 + if (strlen((const char *)cle) <= 1) return -1;
  106 + }
  107 +
  108 + /* LSB Methode ou PARITÉ Methode ou ERREUR */
  109 + if(strcmp(argv[2], "-lsb") == 0) LSB_hide(&I, buff, 0, vig, cle);
  110 + else if (strcmp(argv[2], "-par") == 0) Parity_decode(&I, buff);
  111 + else {
  112 + printf("wrong option [ MUST BE -par OR -lsb ]\n");
  113 + }
  114 +
  115 + if (argc == 5) {
  116 + printf("Cypher : %s\n", buff);
  117 + vigenere(buff, cle, strlen((const char *)cle), 0);
  118 + printf("out\n");
  119 + free(cle);
  120 + }
  121 +
  122 + printf("plaintext : %s\n", buff);
  123 + free(buff);
  124 + }
  125 + else help();
  126 + free_image(&I);
  127 + }
  128 + else {
  129 + help();
  130 + }
  131 + return 0;
  132 +}
0 133 \ No newline at end of file
... ...
src/stegano.c 0 → 100644
  1 +++ a/src/stegano.c
... ... @@ -0,0 +1,193 @@
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <string.h>
  4 +#include <stdint.h>
  5 +#include "../inc/stegano.h"
  6 +
  7 +
  8 +/* Génère une matrice 2D dynamique */
  9 +void NouvelleImage(int width, int height, Image** I)
  10 +{
  11 + *I = malloc(sizeof(Image));
  12 + (*I)->width = width;
  13 + (*I)->height = height;
  14 +
  15 + /* Tableau de pointeur de tableau */
  16 + (*I)->Mat_data = (Pix_rgb **)malloc(height * sizeof(Pix_rgb *));
  17 + /* Allocation de mémoire pour chaque tableau */
  18 + for (int i = 0; i < height; ++i) {
  19 + (*I)->Mat_data[i] = (Pix_rgb *)malloc(width * sizeof(Pix_rgb));
  20 + }
  21 +
  22 + return;
  23 +}
  24 +
  25 +
  26 +/* Libere l'espace mémoire alloué à la structure Image */
  27 +void free_image(Image** I) {
  28 +
  29 + for (int i = 0; i < (*I)->height; ++i)
  30 + free((*I)->Mat_data[i]);
  31 +
  32 + free((*I)->Mat_data);
  33 + free(*I);
  34 +}
  35 +
  36 +
  37 +/* Lit l'entete d'un fichier ppm pour extraire la taille */
  38 +void read_header(FILE * im_file, int *width, int *height) {
  39 +
  40 + char * buff = malloc(10*sizeof(char));
  41 + char * line = NULL;
  42 + size_t len = 0;
  43 + int nb_line = 0;
  44 +
  45 + /* Ignore les commentaire jusqu'à la ligne contenant la taille */
  46 + while (nb_line != 2) {
  47 + getline(&line, &len, im_file);
  48 + if (strncmp(line, "#", 1) != 0) {
  49 + nb_line ++;
  50 + }
  51 + }
  52 +
  53 + /* Recupere la taille */
  54 + strcpy(buff, strtok(line, " "));
  55 + *width = atoi(buff);
  56 + strcpy(buff, strtok(NULL, " "));
  57 + *height = atoi(buff);
  58 +
  59 + getline(&line, &len, im_file);
  60 + free(buff);
  61 +}
  62 +
  63 +
  64 +/* Charge l'image au sein d'une matrice */
  65 +int chargement_ppm(char *image_name, Image** I) {
  66 +
  67 + /* Ouverture du fichier image .ppm */
  68 + FILE* im_file = NULL;
  69 + if((im_file = fopen(image_name,"r")) == NULL) return -1;
  70 +
  71 + int width, height;
  72 +
  73 + read_header(im_file, &width, &height);
  74 + printf("SIZE : %d %d\n", width, height);
  75 +
  76 + /* RECUPERATION ET STOCKAGE DES PIXELS */
  77 + NouvelleImage(width,height, I);
  78 + for (int i=0; i < (*I)->height; i++) {
  79 + for (int j=0; j < (*I)->width ; j++) {
  80 +
  81 + fscanf(im_file, "%c", &((*I)->Mat_data[i][j].red));
  82 + fscanf(im_file, "%c", &((*I)->Mat_data[i][j].green));
  83 + fscanf(im_file, "%c", &((*I)->Mat_data[i][j].blue));
  84 + }
  85 + }
  86 + fclose(im_file);
  87 + return 0;
  88 +}
  89 +
  90 +
  91 +/* Crée une nouvelle image .ppm à partir d'une structure Image */
  92 +int sauvegarde_ppm(char* image_name, Image** I) {
  93 +
  94 + FILE* out = fopen(image_name, "w");
  95 + if(!out) return -1;
  96 +
  97 + fprintf(out, "P6\n%d %d\n255\n", (*I)->width, (*I)->height);
  98 +
  99 + for (int i=0; i < (*I)->height; i++) {
  100 + for (int j=0; j < (*I)->width ; j++) {
  101 +
  102 + fprintf(out, "%c", (*I)->Mat_data[i][j].red);
  103 + fprintf(out, "%c", (*I)->Mat_data[i][j].green);
  104 + fprintf(out, "%c", (*I)->Mat_data[i][j].blue);
  105 + }
  106 + }
  107 + fclose(out);
  108 + printf("saveOK\n");
  109 + return 0;
  110 +}
  111 +
  112 +
  113 +/* Copie les 2 bits de poids faible de x pour les stocker dans le 1eme quart de a */
  114 +void GetPartChar(unsigned char x, unsigned char *a, int i) {
  115 +
  116 + unsigned char mask = 0x03; //0b00000011
  117 + *a += (x & mask) << (i-1)*2;
  118 +}
  119 +
  120 +
  121 +/* Copie le ieme quart de a pour les stocker dans les 2 bits de poids faible de x */
  122 +void SetPartChar(unsigned char *x, unsigned char a, int i) {
  123 +
  124 + unsigned char mask = 0x03; //0b00000011
  125 + unsigned char tmp;
  126 +
  127 + tmp = a & (mask << (i-1)*2); //Decale mask pour obtenir un masque sur le ieme quart
  128 + *x = (*x & 0xFC) | (tmp >> (i-1)*2);//Place les 2 bits au niveau du poids faible de x
  129 +}
  130 +
  131 +
  132 +/* Determine dans quel pixels l'information est/sera dissimulée
  133 + L'utilisation d'un chiffrement vigenere (int vigenere == 1) et donc d'une clé (unsigned char *cle)
  134 + influe sur la détermination des pixels */
  135 +void Next_pixel(Image **I, int *current_pos, int *i, int *j, int vigenere, unsigned char *cle) {
  136 +
  137 + int h = (*I)->height;
  138 + int w = (*I)->width;
  139 + int im_size = h * w;
  140 +
  141 + *current_pos += ((*I)->Mat_data[(*i)][(*j)].red & (*I)->Mat_data[(*i)][(*j)].green) / 5;
  142 + *current_pos += 1;
  143 +
  144 + if (vigenere) {
  145 + int icle = *current_pos % strlen((const char *)cle);
  146 + *current_pos += (*current_pos & cle[icle]) / 5;
  147 + }
  148 + int tmp_pos = *current_pos;
  149 +
  150 + if (tmp_pos % 2 == 0) tmp_pos = im_size - tmp_pos;
  151 + //tmp_pos = tmp_pos % (w*h);
  152 + //printf("pos %d\n", tmp_pos);
  153 + *i = tmp_pos / w;
  154 + *j = tmp_pos % w;
  155 +}
  156 +
  157 +
  158 +/* Cache ou extrait un unsigned char *msg au sein de la matrice Image **I
  159 + int encode = 1 -> cache le message
  160 + = 0 -> extrait le message
  161 + int vigenere -> permet de savoir si un chiffrement vigenere a été ou doit être effectué (utile pour Next_pixel)
  162 + unsigned char *clef -> utilisé en cas de chiffrement avec vigenere */
  163 +void LSB_hide(Image **I, unsigned char *msg, int encode, int vigenere, unsigned char *cle) {
  164 +
  165 + uint8_t k = 0;
  166 + int quart = 1;
  167 +
  168 + int h = (*I)->height;
  169 + int w = (*I)->width;
  170 + int i = 0;
  171 + int j = 0;
  172 + int current_pos = i*h + j;
  173 +
  174 + /* dissimulation ou extraction message */
  175 + while(1) {
  176 + Next_pixel(I, &current_pos, &i, &j, vigenere, cle);
  177 + if (encode == 1) SetPartChar(&((*I)->Mat_data[i][j].blue), msg[k], quart);
  178 + else GetPartChar((*I)->Mat_data[i][j].blue, &msg[k], quart);
  179 + quart += 1;
  180 + if (quart == 5) {
  181 + quart = 1;
  182 + if ( msg[k] == '\0') return;
  183 + k ++;
  184 + }
  185 + if (current_pos >= h*w) return;
  186 + }
  187 +}
  188 +
  189 +
  190 +
  191 +/* TODO
  192 +1- vidage du buffer
  193 +*/
0 194 \ No newline at end of file
... ...
src/vigenere.c 0 → 100644
  1 +++ a/src/vigenere.c
... ... @@ -0,0 +1,41 @@
  1 +#include <stdio.h>
  2 +#include<stdlib.h>
  3 +#include <ctype.h>
  4 +#include <string.h>
  5 +#include "../inc/vigenere.h"
  6 +
  7 +char * message;
  8 +char * cle;
  9 +int tailleCle;
  10 +
  11 +
  12 +/* Fonction de chiffrement ou déchiffrement Vigenere
  13 + Chiffre/Dechifffe le char *message avec la char *cle de taille int tailleCle
  14 + Si int encode = 1 -> chiffrement, Si int encode = 0 -> dechiffre */
  15 +void vigenere(unsigned char *message, unsigned char *cle, int tailleCle, int encode)
  16 +{
  17 + int iCle = 0;
  18 +
  19 + /* Parcours du message */
  20 + for (int iMsg = 0; message[iMsg] != '\0'; iMsg++) {
  21 +
  22 + /* Si notre caractère est un caractère alphanumérique */
  23 + if(isalpha(message[iMsg])) {
  24 + char casse, lettreCle;
  25 +
  26 + //casse = 'A' si 'A' < message[iMsg] < 'Z'
  27 + //casse = 'a' si 'a' < message[iMsg] < 'z'
  28 + casse = (isupper(message[iMsg])) ? 'A' : 'a';
  29 + lettreCle = tolower(cle[iCle]) - 'a';
  30 + iCle = (iCle + 1) % tailleCle;
  31 +
  32 + /* On se ramène à des lettres codées dans [0:26] pour pouvoir appliqué les formules suivantes */
  33 + message[iMsg] -= casse;
  34 + if (encode) message[iMsg] = ((message[iMsg] + lettreCle) % 26+ 26) % 26; // CHIFFREMENT
  35 + else message[iMsg] = ((message[iMsg] - lettreCle) % 26 + 26) % 26; // DECHIFFREMENT
  36 +
  37 + /* On rétablie le code ascii (65 à 90 pour les majuscule, 97 à 122 pour les minuscules) */
  38 + message[iMsg] += casse;
  39 + }
  40 + }
  41 +}
0 42 \ No newline at end of file
... ...