CS50 'Recover' 问题 - 图像不完整 - 两个不正确的字节
CS50 'Recover' Problem - Incomplete Images - Two Incorrect Bytes
先post到这里,希望对大家有所帮助!抱歉,篇幅太长了 - 只是想说的很透彻。
我正在研究 CS50 问题集 4,我偶然发现了一个有趣的问题,但我还没有解决。我成功恢复了 49 张图像,大约一半的图像似乎已正确恢复。但是,根据来自 Windows Explorer 的 attached image,其余图像在文件末尾具有不同程度的“损坏”数据。
鉴于这发生在文件的中间,而且我似乎正确地找到了每个文件的开头,我相信这发生在我的 while 循环的后半部分 - 即“不是 jpg header”。我们被告知 jpg 文件背靠背存储在原始数据上,所以我认为我不需要考虑 jpg 文件末尾的任何异常。
我已经进行了一些测试来尝试解决这个问题,但到目前为止没有成功:
- 通过与 card.raw.
进行比较,验证总输出文件大小是否正确
- 已验证我的 while 循环的后半部分运行图像的预期次数 001.jpg - 第一个有问题。
- 运行 在另一个 IDE
- 检查文件大小是否与“损坏”文件有关,因为 successful/unsuccessful 输出没有明显的模式。
- 我认为可能是根本原因的区域中的各种语法更改(缓冲区变量的定义,
fread/fwrite 语句模式。)
我最后的调试工作是将我的 001.jpg 版本与完成此问题集的朋友提供的已知正确版本 001.jpg 进行比较。我在十六进制编辑器中比较了这些,发现有两个字节(总共 105984)不正确。在第 00002400 行和第 00012400 行,我用“d8”代替了 jpg 文件的十六进制视图中的“00”。没有进一步的差异。
我在下面包含了我认为相关的代码区域以及 check50 结果。如果需要,我很乐意提供更多代码。我觉得我现在已经达到了我的理解极限,我不确定如何继续解决这个问题。 任何人都可以就这里可能出现的问题给我一些建议吗?
代码示例:
#include <stdint.h> //required for uint8_t
#include <stdio.h>
#include <stdlib.h>
const int SEG_SIZE = 512;
typedef uint8_t BYTE; //declaring byte to simplify code below
int main(int argc, char *argv[])
{
//check if single argument has been applied, give usage instructions if not.
//retracted
//open memory card file
// retracted code
//error handle
// retracted code
//define variables
BYTE buffer[SEG_SIZE]; //char=1 byte. 512 byte buffer for reading file.
char img_filename[8];
int count = -1; //declaring counter for number of files found. Starting at -1, allowing first found file to be number 0.
//declare jpg file. Declaring in loop produces errors, local variable is 'block scoped'.
FILE *img = NULL;
//repeat until end of card
while (fread(buffer, SEG_SIZE, 1, input)) //read 512 byte samples into buffer until end of file. returns number of items successfully read from file (i.e. 1)
{
//if start of new jpg
if ((buffer[0]==0xff) && (buffer[1]=0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0)) // retracted code //checking if first four bytes match the beginning of a new jpg.
{
count++;
if (count == 0) //found first image in raw data.
{
//retracted code - creates filename and opens file.
}
else
{
//closing previous file
// retracted code
img = fopen(img_filename, "w"); //opening next image file.
fwrite(buffer, SEG_SIZE, 1, img);
}
}
else if (count >= 0) //required to prevent running this code before declaring a file.
{
fwrite(buffer, SEG_SIZE, 1, img); //continue writing to current file, if present
}
}
// retracted code
}
检查 50 个结果:
Results for cs50/problems/2021/x/recover generated by check50 v3.2.2
:) recover.c exists.
:) recover.c compiles.
:) handles lack of forensic image
:) recovers 000.jpg correctly
:( recovers middle images correctly
recovered image does not match
:) recovers 049.jpg correctly
提前致谢,
安迪.
这一行少了一个=
:
if ((buffer[0]==0xff) && (buffer[1]=0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0)) //checking if first four bytes match the beginning of a new jpg.
编译器不会给出“表达式不可赋值”错误,因为括号会更改表达式“是”的内容。 buffer[1] = 0xd8
(没有括号)会给出错误。除了 (buffer[3] & 0xf0)
,内部括号是无关的。
FILE *img = NULL;
int counter = 0;
char image[8];
BYTE data[BLOCK];
//checking if the end of the card is reached
while (fread(&data, sizeof(BLOCK), 1, card) != 0)
{
//checking if it's a new jpeg
if (data[0] == 0xff && data[1] == 0xd8 && data[2] == 0xff && (data[3] & 0xf0)==0xe0)
{
//if it's not the first new jpeg, close the previous
if (img != NULL)
{
fclose(img);
}
sprintf(image, "%03i.jpg", counter);
img = fopen(image, "w");
if (img == NULL)
{
fprintf(stderr, "Couldn't open %s!\n", image);
fclose(card);
return 3;
}
counter++;
}
if (img != NULL)
{
fwrite(&data, sizeof(BLOCK), 1, img);
}
}
fclose(img);
fclose(card);
return 0;
}
先post到这里,希望对大家有所帮助!抱歉,篇幅太长了 - 只是想说的很透彻。
我正在研究 CS50 问题集 4,我偶然发现了一个有趣的问题,但我还没有解决。我成功恢复了 49 张图像,大约一半的图像似乎已正确恢复。但是,根据来自 Windows Explorer 的 attached image,其余图像在文件末尾具有不同程度的“损坏”数据。
鉴于这发生在文件的中间,而且我似乎正确地找到了每个文件的开头,我相信这发生在我的 while 循环的后半部分 - 即“不是 jpg header”。我们被告知 jpg 文件背靠背存储在原始数据上,所以我认为我不需要考虑 jpg 文件末尾的任何异常。
我已经进行了一些测试来尝试解决这个问题,但到目前为止没有成功:
- 通过与 card.raw. 进行比较,验证总输出文件大小是否正确
- 已验证我的 while 循环的后半部分运行图像的预期次数 001.jpg - 第一个有问题。
- 运行 在另一个 IDE
- 检查文件大小是否与“损坏”文件有关,因为 successful/unsuccessful 输出没有明显的模式。
- 我认为可能是根本原因的区域中的各种语法更改(缓冲区变量的定义, fread/fwrite 语句模式。)
我最后的调试工作是将我的 001.jpg 版本与完成此问题集的朋友提供的已知正确版本 001.jpg 进行比较。我在十六进制编辑器中比较了这些,发现有两个字节(总共 105984)不正确。在第 00002400 行和第 00012400 行,我用“d8”代替了 jpg 文件的十六进制视图中的“00”。没有进一步的差异。
我在下面包含了我认为相关的代码区域以及 check50 结果。如果需要,我很乐意提供更多代码。我觉得我现在已经达到了我的理解极限,我不确定如何继续解决这个问题。 任何人都可以就这里可能出现的问题给我一些建议吗?
代码示例:
#include <stdint.h> //required for uint8_t
#include <stdio.h>
#include <stdlib.h>
const int SEG_SIZE = 512;
typedef uint8_t BYTE; //declaring byte to simplify code below
int main(int argc, char *argv[])
{
//check if single argument has been applied, give usage instructions if not.
//retracted
//open memory card file
// retracted code
//error handle
// retracted code
//define variables
BYTE buffer[SEG_SIZE]; //char=1 byte. 512 byte buffer for reading file.
char img_filename[8];
int count = -1; //declaring counter for number of files found. Starting at -1, allowing first found file to be number 0.
//declare jpg file. Declaring in loop produces errors, local variable is 'block scoped'.
FILE *img = NULL;
//repeat until end of card
while (fread(buffer, SEG_SIZE, 1, input)) //read 512 byte samples into buffer until end of file. returns number of items successfully read from file (i.e. 1)
{
//if start of new jpg
if ((buffer[0]==0xff) && (buffer[1]=0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0)) // retracted code //checking if first four bytes match the beginning of a new jpg.
{
count++;
if (count == 0) //found first image in raw data.
{
//retracted code - creates filename and opens file.
}
else
{
//closing previous file
// retracted code
img = fopen(img_filename, "w"); //opening next image file.
fwrite(buffer, SEG_SIZE, 1, img);
}
}
else if (count >= 0) //required to prevent running this code before declaring a file.
{
fwrite(buffer, SEG_SIZE, 1, img); //continue writing to current file, if present
}
}
// retracted code
}
检查 50 个结果:
Results for cs50/problems/2021/x/recover generated by check50 v3.2.2
:) recover.c exists.
:) recover.c compiles.
:) handles lack of forensic image
:) recovers 000.jpg correctly
:( recovers middle images correctly
recovered image does not match
:) recovers 049.jpg correctly
提前致谢,
安迪.
这一行少了一个=
:
if ((buffer[0]==0xff) && (buffer[1]=0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0)) //checking if first four bytes match the beginning of a new jpg.
编译器不会给出“表达式不可赋值”错误,因为括号会更改表达式“是”的内容。 buffer[1] = 0xd8
(没有括号)会给出错误。除了 (buffer[3] & 0xf0)
,内部括号是无关的。
FILE *img = NULL;
int counter = 0;
char image[8];
BYTE data[BLOCK];
//checking if the end of the card is reached
while (fread(&data, sizeof(BLOCK), 1, card) != 0)
{
//checking if it's a new jpeg
if (data[0] == 0xff && data[1] == 0xd8 && data[2] == 0xff && (data[3] & 0xf0)==0xe0)
{
//if it's not the first new jpeg, close the previous
if (img != NULL)
{
fclose(img);
}
sprintf(image, "%03i.jpg", counter);
img = fopen(image, "w");
if (img == NULL)
{
fprintf(stderr, "Couldn't open %s!\n", image);
fclose(card);
return 3;
}
counter++;
}
if (img != NULL)
{
fwrite(&data, sizeof(BLOCK), 1, img);
}
}
fclose(img);
fclose(card);
return 0;
}