-
-
Save CraigRodrigues/8f831e9ea1003d9ad14f608d24cc1ba3 to your computer and use it in GitHub Desktop.
/** | |
* recover.c | |
* | |
* Computer Science 50 | |
* Problem Set 4 | |
* | |
* Recovers JPEGs from a forensic image. | |
*/ | |
#include <cs50.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define BUFFER_SIZE 512 | |
int main(void) | |
{ | |
// open memory card file | |
FILE* input = fopen("card.raw", "r"); | |
if (input == NULL) | |
{ | |
printf("Could not open card.raw.\n"); | |
return 2; | |
} | |
// create buffer | |
unsigned char buffer[BUFFER_SIZE]; | |
// filename counter | |
int filecount = 0; | |
FILE* picture = NULL; | |
// check if we've found a jpeg yet or not | |
int jpg_found = 0; //false | |
// go through cardfile until there aren't any blocks left | |
while (fread(buffer, BUFFER_SIZE, 1, input) == 1) | |
{ | |
// read first 4 bytes of buffer and see if jpg signature using bitwise on last byte | |
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xe0) == 0xe0) | |
{ | |
if (jpg_found == 1) | |
{ | |
// We found the start of a new pic so close out current picture | |
fclose(picture); | |
} | |
else | |
{ | |
// jpg discovered and now we have the green light to write | |
jpg_found = 1; | |
} | |
char filename[8]; | |
sprintf(filename, "%03d.jpg", filecount); | |
picture = fopen(filename, "a"); | |
filecount++; | |
} | |
if (jpg_found == 1) | |
{ | |
// write 512 bytes to file once we start finding jpgs | |
fwrite(&buffer, BUFFER_SIZE, 1, picture); | |
} | |
} | |
// close files | |
fclose(input); | |
fclose(picture); | |
return 0; | |
} |
why is while(........ = 1 ) for fread
why is while(........ = 1 ) for fread
to stop executing if it didn't find block of 512 bytes in the memory
why is while(........ = 1 ) for fread
to stop executing if it didn't find block of 512 bytes in the memory
Does this mean something like "while fread is true: ..." ?
Why do you need the cs50 library
hello! could you please explain why the first fread uses buffer while the next fread at the end uses &buffer instead? thank you!
Hey nice work! You could also avoid the boolean flag just by checking the image file! if it is NULL then you can start writing, otherwise you close the file and create a new image! just to simplify the code!
~/pset4/recover/ $ ./a.out
Could not open card.raw.
someone help!
@Student3153 Are you using this code?
Hey, thank you for sharing your solution. Can you please explain to me, why in line 60 another if statement is needed? I would have used else, however, that does not work and it is giving me segmentation faults.
Thank you.
Hey, thank you for sharing your solution. Can you please explain to me, why in line 60 another if statement is needed? I would have used else, however, that does not work and it is giving me segmentation faults.
The "if (jpg_found == 1)" in line 60 is used for writing the bytes on an already existing jpg file
the if condition in 43 checks if a new file was found so you cant use a else condition because the 43 and 60 works together
~/pset4/recover/ $ ./a.out
Could not open card.raw.
someone help!
you need to put your file's name as follow :
FILE* file = fopen("card.raw", "r");
@frjimbow I’m already done with the entire course
@frjimbow I’m already done with the entire course
sounds great. Have you become a professional developer ?
why the &buffer ?
just buffer is ok
hello,
if (jpg_found == 1) { // We found the start of a new pic so close out current picture fclose(picture); }
i delete and it s work,
why it s important these lines
i think we close already here
// close files
fclose(input);
fclose(picture);
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define BLK_SIZE 512
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not be opened %s\n", argv[1]);
return 1;
}
FILE *output = NULL;
int imgcount = 0;
BYTE bytes[BLK_SIZE];
while(fread(bytes, sizeof(BYTE), BLK_SIZE, input) || feof(input))
{
if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff && (bytes[3] & 0xf0) == 0xe0)
{
if (output != NULL)
{
fclose(output);
}
char filename[8];
sprintf(filename, "%03i.jpg", imgcount);
output = fopen(filename, "w");
imgcount++;
}
if(output!=NULL)
{
fwrite(bytes, sizeof(BYTE), 1, output);
}
}
if (input == NULL)
{
fclose(input);
}
if(output == NULL)
{
fclose(output);
}
return 0;
}
:) recover.c exists.
:) recover.c compiles.
:) handles lack of forensic image
:( recovers 000.jpg correctly
timed out while waiting for program to exit
:( recovers middle images correctly
timed out while waiting for program to exit
:( recovers 049.jpg correctly
timed out while waiting for program to exit
can someone help me understand whats going on?
Thank you :)
Hello,
The following code is not working, could you please help?
Results :
:) recover.c exists.
:) recover.c compiles.
:) handles lack of forensic image
:( recovers 000.jpg correctly
recovered image does not match
:( recovers middle images correctly
recovered image does not match
:( recovers 049.jpg correctly
recovered image does not match
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#define BLOCK 512
#define FILENAME_LENGTH 8
bool isJPEG(unsigned char buffer[]){
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
return true;
}
return false;
}
int main(int argc, char *argv[])
{
//argv[1]
FILE *inFile = fopen(argv[1], "rb");
if (argc != 2)
{
return 1;
}
if (argv[1] == NULL)
{
fprintf(stderr, "Usage: ./recover image");
return 1;
}
//each JPEG file start with a distinct header
//all first 3 bytes in JPEG files are the same : 0xff - 0xd8 - 0xff
// the fourth byte : 0xe0, 0xe1, 0xe2, ...., or 0xef
//the JPEG files are stored back to back in the memory card
//each block is 512 bytes
int count = 0;
unsigned char buffer[BLOCK];
bool found = false;
FILE *outFile;
//read until the end
while (fread(buffer, sizeof(buffer), 1, inFile) == 1)
{
if (isJPEG(buffer) == true)
{
if (found == true)
{
// Close outfile
fclose(outFile);
}
else
{
found = true;
}
char outFileName[FILENAME_LENGTH];
sprintf(outFileName, "%03i.jpg", count);
outFile = fopen(outFileName, "wb");
count++;
if (found == true)
{
if (fwrite(buffer, sizeof(buffer), 1, outFile) != 1)
{
fprintf(stderr, "error writing");
}
}
}
}
fclose(outFile);
fclose(inFile);
return 0;
}
Thanks!
hello! could you please explain why the first fread uses buffer while the next fread at the end uses &buffer instead? thank you!
Hi, I had the same doubt. i guess this will help you out, after a bit research i found this answer helpful.
https://stackoverflow.com/a/53471904
why the &buffer ?
it is useless since the buffer array is already a pointer holding the address of the first element in it
Thanks a lot!
to create memory space for the filename