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 @@ | @@ -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 | \ No newline at end of file | 8 | \ No newline at end of file |
1 | +++ a/inc/stegano.h | ||
@@ -0,0 +1,27 @@ | @@ -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 | \ No newline at end of file | 28 | \ No newline at end of file |
1 | +++ a/makefile | ||
@@ -0,0 +1,13 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 | \ No newline at end of file | 133 | \ No newline at end of file |
1 | +++ a/src/stegano.c | ||
@@ -0,0 +1,193 @@ | @@ -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 | \ No newline at end of file | 194 | \ No newline at end of file |
1 | +++ a/src/vigenere.c | ||
@@ -0,0 +1,41 @@ | @@ -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 | \ No newline at end of file | 42 | \ No newline at end of file |