Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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;
}