Commit 17ba8f8f9b0b9513fd9513135aec09215d29bb64
0 parents
Ajout du code
Showing
11 changed files
with
615 additions
and
0 deletions
Show diff stats
No preview for this file type
No preview for this file type
No preview for this file type
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 | ... | ... |
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 | ... | ... |
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 | ... | ... |
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 | +} | ... | ... |
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 | ... | ... |
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, ¤t_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 | ... | ... |
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 | ... | ... |