The following program takes a PPM image and will either encrypt or decrypt it wh
ID: 3751523 • Letter: T
Question
The following program takes a PPM image and will either encrypt or decrypt it when supplied with a key. Find the errors and fix them, then run the program to decrypt the image. Use the secret.ppm and key below as the source, key as the crypto key, and decrypted.ppm as the location of the generated image.
Fix the errors and determine the decrypted image below using the key and 3 files in the C program.
/********************************************/
key: 22695477
secret.ppm
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "stdio.h"
#include "stdlib.h"
#include "crypto.h"
int main(int argc, char const *argv[]) {
FILE* image_file = fopen(argv[1], "r");
FILE* key_file = fopen(argv[2], "r");
FILE* out_image = fopen(argv[3], "w");
// Read image
header_t header;
img_t img;
read_header(image_file, header);
read_image(image_file, &img, &header);
// Read secret key
int seed;
read_seed(key_file, *seed);
sp_rand(eed);
/** NO ERROR HERE **/
printf("Encrypt[1] or Decrypt[2]? ");
int choice;
while(true) {
scanf("%d",&choice);
if(choice == 1 || choice == 2) {
sym_crypt(out_image, &header, &img, choice);
break;
} else {
printf("Please enter 1 or 2 ");
}
}
/********************/
fclose(image_file);
fclose(key_file);
fclose(out_image);
return 0;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "crypto.h"
int P_RAND_SEED = 1;
/** NO ERRORS HERE! **/
void read_header(FILE* in_img, header_t* header) {
header->type = malloc(sizeof(char)*3);
fscanf(in_img, "%s ", header->type);
fscanf(in_img, "%d %d ", &header->w, &header->h);
fscanf(in_img, "%d ", &header->cs);
printf("Header: %s %d %d %d ", header->type, header->w, header->h, header->cs);
}
/********************/
/** Could be errors... **/
void read_image(FILE* input, img_t* image, header_t* header) {
int row, col;
image->data = malloc(sizeof(pixel_t*) * header.h);
for(row = 0; row < header->h; row++) {
image->data[row] = malloc(sizeof(pixel_t) * header->w * 3);
for(; col < header->w; col++) {
pixel_t pix
fscanf(input, "%c%c%c", &pix.r, &pix.g, &pix.b);
image.data[row][col] = pix;
}
}
}
/** NO ERRORS HERE! **/
void read_seed(FILE* seed_file, int* seed) {
fscanf(seed_file, "%d", seed);
}
/** Could be errors... **/
void sym_crypt(FILE* output, header_t* header, img_t* image, int mode) {
// Write header of PPM to files
/** NO ERRORS HERE! **/
fprintf(output, "%s %d %d %d ", header->type, header->w, header->h, header->cs);
/*********************/
// Encrypt or Decrypt!
// Could be errors...
int row, col;
switch (mode) {
case 1:
printf("Encrypt ", );
for(row = 0; row < header->h; row++) {
for(col = 0; col < header->w; col++) {
int swap_row = p_rand(row*row) % header.h;
int swap_col = p_rand(col*col) % header->w;
pixel_t swap = image->data[row][col];
image->data[row][col] = image->data[swap_row][swap_col];
image->data[swap_row][swap_col] = swap;
}
} break;
case 2:
printf("Decrypt ");
for(row = header->h-1; row >= 0; row--) {
for(; col >= 0; col--) {
int swap_row = p_rand(row*row) % header->h;
int swap_col = p_rand(col*col) % header->w;
pixel_t swap = image->data[row][col];
image->data[row][col] = image->data[swap_row][swap_col];
image->data[swap_row][swap_col] = swap;
}
} break;
default: break;
}
/** NO ERRORS HERE! **/
for(row = 0; row < header->h; row++) {
for(col = 0; col < header->w; col++) {
pixel_t pix = image->data[row][col];
fprintf(output, "%c%c%c", pix.r, pix.g, pix.b);
}
}
/********************/
}
/** NO ERRORS HERE! **/
void sp_rand(unsigned int seed) {
P_RAND_SEED = seed;
}
/********************/
/** NO ERRORS HERE! **/
unsigned int p_rand(unsigned int init) {
return (P_RAND_SEED*init) % INT_MAX;
}
/********************/
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#ifndef CRYPTO_H
#define CRYPTO_H value
#include "stdio.h"
#include "stdlib.h"
#include "limits.h"
#include "stdbool.h"
extern int P_RAND_SEED;
typedef struct header_t {
char* type;
int w, h, cs;
} header_t;
typedef struct pixel_t {
unsigned char r,g,b;
} pixel_t;
typedef struct img_t {
pixel_t** data;
} img_t;
void read_header(FILE* in_img, header_t* header);
void read_image(FILE* in_img, img_t* image, header_t* header);
void read_seed(FILE* seed_file, int* seed);
void sym_crypt(FILE* out_img, header_t* header, img_t* image, int mode);
// Dumb random number generator
void sp_rand(unsigned int seed);
unsigned int p_rand(unsigned int init);
#endif
Explanation / Answer
First of all we correct errors out of each file. The major suggestion is to look into the Function declaration or prototypes existing in the parallel header file and follow/conform to so as to.
crypto.h
No errors here
#ifndef CRYPTO_H
#define CRYPTO_H value
#include "stdio.h"
#include "stdlib.h"
#include "limits.h"
#include "stdbool.h"
extern int P_RAND_SEED;
typedef struct header_t {
char* type;
int w, h, cs;
} header_t;
typedef struct pixel_t {
unsigned char r,g,b;
} pixel_t;
typedef struct img_t {
pixel_t** data;
} img_t;
void read_header(FILE* in_img, header_t* header);
void read_image(FILE* in_img, img_t* image, header_t* header);
void read_seed(FILE* seed_file, int* seed);
void sym_crypt(FILE* out_img, header_t* header, img_t* image, int mode);
// random number generator //
void sp_rand(unsigned int seed);
unsigned int p_rand(unsigned int init);
#endif
main.c
#include "stdio.h"
#include "stdlib.h"
#include "crypto.h"
int main(int argc, char const *argv[]) {
FILE* image_file = fopen(argv[1], "r");
FILE* key_file = fopen(argv[2], "r");
FILE* out_image = fopen(argv[3], "w");
// Read image
header_t header;
img_t img;
Error 1:
read_header(image_file, header);
According to read_header declaration, 2nd argument
should be a pointer to header_t i.e. header_t *
void read_header(FILE* in_img, header_t* header);
But here value was being passed in place of address
leading to incompatible type error
Fix is to pass the address of variable
read_header(image_file, &header);
read_image(image_file, &img, &header);
// Read secret key
int seed;
Error 2:
read_seed(key_file, *seed);
Prototype for read_seed
void read_seed(FILE* seed_file, int* seed);
'seed' variable is of int type and not a pointer type
thus we see error here, this is fixed by passing address
of seed variable.
read_seed(key_file, &seed);
Error 3:
sp_rand(eed);
This is just a simple typing (aka typo) error
it should be 'seed' rather than 'eed'
sp_rand(seed);
printf("Encrypt[1] or Decrypt[2]? ");
int choice;
while(true) {
scanf("%d",&choice);
if(choice == 1 || choice == 2) {
sym_crypt(out_image, &header, &img, choice);
break;
} else {
printf("Please enter 1 or 2 ");
}
}
/********************/
fclose(image_file);
fclose(key_file);
fclose(out_image);
return 0;
}
crypto.c
#include "crypto.h"
int P_RAND_SEED = 1;
void read_header(FILE* in_img, header_t* header) {
header->type = malloc(sizeof(char)*3);
fscanf(in_img, "%s ", header->type);
fscanf(in_img, "%d %d ", &header->w, &header->h);
fscanf(in_img, "%d ", &header->cs);
printf("Header: %s %d %d %d ", header->type, header->w, header->h, header->cs);
}
Fix errors...
void read_image(FILE* input, img_t* image, header_t* header) {
int row, col;
Error 1:
image->data = malloc(sizeof(pixel_t*) * header.h);
As here header variable is a pointer to structure type
then right way/operator to get the value of h will be
arrow '->' operator
image->data = malloc(sizeof(pixel_t*) * header->h);
for(row = 0; row < header->h; row++) {
image->data[row] = malloc(sizeof(pixel_t) * header->w * 3);
for(; col < header->w; col++) {
Error 2:
pixel_t pix
';' is missing after the declaration
pixel_t pix;
fscanf(input, "%c%c%c", &pix.r, &pix.g, &pix.b);
Error 3:
image.data[row][col] = pix;
image variable is a pointer to structure type
then right way/operator to get the value of h will be
arrow '->' operator
image->data[row][col] = pix;
}
}
}
void read_seed(FILE* seed_file, int* seed) {
fscanf(seed_file, "%d", seed);
}
Fix errors...
void sym_crypt(FILE* output, header_t* header, img_t* image, int mode) {
// Write header of PPM to files
fprintf(output, "%s %d %d %d ", header->type, header->w, header->h, header->cs);
// Encrypt or Decrypt!
// fix errors //
int row, col;
switch (mode) {
case 1:
Error 4:
printf("Encrypt ", );
This seems to be typo error
As here printf is expecting some expression after ','
Now, as we don't have any format specifiers, we don't
need this ','
printf("Encrypt ");
for(row = 0; row < header->h; row++) {
for(col = 0; col < header->w; col++) {
int swap_row = p_rand(row*row) % header->h;
int swap_col = p_rand(col*col) % header->w;
pixel_t swap = image->data[row][col];
image->data[row][col] = image->data[swap_row][swap_col];
image->data[swap_row][swap_col] = swap;
}
} break;
case 2:
printf("Decrypt ");
for(row = header->h-1; row >= 0; row--) {
for(; col >= 0; col--) {
Error 5:
int swap_row = p_rand(row*row) % header.h;
As here header variable is a pointer to structure type
then right way/operator to get the value of h will be
arrow '->' operator
int swap_row = p_rand(row*row) % header->h;
int swap_col = p_rand(col*col) % header->w;
pixel_t swap = image->data[row][col];
image->data[row][col] = image->data[swap_row][swap_col];
image->data[swap_row][swap_col] = swap;
}
} break;
default: break;
}
for(row = 0; row < header->h; row++) {
for(col = 0; col < header->w; col++) {
pixel_t pix = image->data[row][col];
fprintf(output, "%c%c%c", pix.r, pix.g, pix.b);
}
}
}
void sp_rand(unsigned int seed) {
P_RAND_SEED = seed;
}
unsigned int p_rand(unsigned int init) {
return (P_RAND_SEED*init) % INT_MAX;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.