Escolar Documentos
Profissional Documentos
Cultura Documentos
Voltar
Anterior
Próximo
Exercício 3 - Recover
Implemente um programa que recupere JPEGs de uma imagem forense, conforme a seguir.
$ ./recover card.raw
Background
Prevendo esse problema, passamos os últimos dias tirando fotos de pessoas que conhecemos,
todas as quais foram salvas em uma câmera digital como JPEG em um cartão de memória. (Ok, é
possível que, em vez disso, tenhamos passado os últimos dias no Facebook.) Infelizmente, de
alguma forma excluímos todos eles! Felizmente, no mundo da informática, "excluído" tende a não
significar "excluído", mas sim "esquecido". Mesmo que a câmera insista que o cartão agora está
em branco, temos certeza de que isso não é bem verdade. Na verdade, estamos torcendo (er,
esperando!) Que você possa escrever um programa que recupere as fotos para nós!
Mesmo que JPEGs sejam mais complicados do que BMPs, JPEGs têm “assinaturas”, padrões de
bytes que podem distingui-los de outros formatos de arquivo. Especificamente, os primeiros três
bytes de JPEGs são
do primeiro para o terceiro byte, da esquerda para a direita. O quarto byte, entretanto, é 0xe0 ,
0xe1 , 0xe2 , 0xe3 , 0xe4 , 0xe5 , 0xe6 , 0xe7 , 0xe8 , 0xe9 , 0xea , 0xeb ,
0xec , 0xed , 0xee ou 0xef . Dito de outra forma, os primeiros quatro bits do quarto byte
são 1110 .
As probabilidades são de que, se você encontrar esse padrão de quatro bytes na mídia
conhecida por armazenar fotos (por exemplo, meu cartão de memória), eles demarcam o início de
https://ead.napratica.org.br/enrollments/7235444/courses/84414/course_contents/2169400 1/5
01/07/2022 14:53 Fundação Estudar
um JPEG. Para ser justo, você pode encontrar esses padrões em algum disco puramente por
acaso, então a recuperação de dados não é uma ciência exata.
A implicação de todos esses detalhes é que você, o investigador, provavelmente pode escrever
um programa que itera sobre uma cópia do meu cartão de memória, procurando assinaturas de
JPEGs. Cada vez que encontrar uma assinatura, você pode abrir um novo arquivo para escrever e
começar a preencher esse arquivo com bytes do meu cartão de memória, fechando esse arquivo
apenas quando encontrar outra assinatura. Além disso, em vez de ler os bytes do meu cartão de
memória um de cada vez, você pode ler 512 deles por vez em um buffer para fins de eficiência.
Graças ao FAT, você pode confiar que as assinaturas de JPEGs serão "alinhadas em bloco". Ou
seja, você só precisa procurar essas assinaturas nos primeiros quatro bytes de um bloco.
Perceba, é claro, que JPEGs podem abranger blocos contíguos. Caso contrário, nenhum JPEG
pode ser maior que 512 B. Mas o último byte de um JPEG pode não cair no final de um bloco.
Lembre-se da possibilidade de espaço livre. Mas não se preocupe. Como este cartão de memória
era novo quando comecei a tirar fotos, é provável que tenha sido “zerado” (ou seja, preenchido
com 0s) pelo fabricante, caso em que qualquer espaço livre será preenchido com 0s. Tudo bem
se esses 0s finais acabarem nos JPEGs que você recuperar; eles ainda devem estar visíveis.
Agora, só tenho um cartão de memória, mas são muitos de vocês! E então fui em frente e criei
uma “imagem forense” do cartão, armazenando seu conteúdo, byte após byte, em um arquivo
chamado card.raw . Para que você não perca tempo repetindo milhões de zeros
desnecessariamente, imaginei apenas os primeiros megabytes do cartão de memória. Mas você
deve descobrir que a imagem contém 50 JPEGs.
Vamos começar
Veja como baixar o “código de distribuição” desse problema (ou seja, código inicial) em seu
próprio CS50 IDE. Faça login no CS50 IDE e, em uma janela de terminal, execute cada um dos
itens abaixo.
https://ead.napratica.org.br/enrollments/7235444/courses/84414/course_contents/2169400 2/5
01/07/2022 14:53 Fundação Estudar
Especificação
Implemente um programa denominado recover que recupera JPEGs de uma imagem forense.
https://ead.napratica.org.br/enrollments/7235444/courses/84414/course_contents/2169400 3/5
01/07/2022 14:53 Fundação Estudar
Se a imagem forense não puder ser aberta para leitura, seu programa deve informar isso ao
usuário, e main deve retornar 1.
Cada um dos arquivos gerados deve ser nomeado como ###.jpg , onde ### é um número
decimal de três dígitos, começando com 000 para a primeira imagem e aumentando.
Seu programa, se usar malloc , não deve perder memória.
Uso
$ ./recover
$ ./recover card.raw
Dicas
Lembre-se de que você pode abrir card.raw programaticamente com fopen , como abaixo, desde
que argv[1] exista.
As probabilidades são, no entanto, os JPEGs que o primeiro rascunho de seu código divulga não
estarão corretos. (Se você abri-los e não ver nada, provavelmente eles não estão corretos!)
Execute o comando abaixo para excluir todos os JPEGs em seu diretório de trabalho atual.
$ rm * .jpg
Se você preferir não ser solicitado a confirmar cada exclusão, execute o comando abaixo.
$ rm -f * .jpg
Apenas tome cuidado com a opção -f , pois ela “força” a exclusão sem avisar você.
https://ead.napratica.org.br/enrollments/7235444/courses/84414/course_contents/2169400 4/5
01/07/2022 14:53 Fundação Estudar
Se você gostaria de criar um novo tipo para armazenar um byte de dados, você pode fazer isso
por meio do comando abaixo, que define um novo tipo chamado BYTE como uint8_t (um tipo
definido em stdint.h , representando um inteiro sem sinal).
Lembre-se também de que você pode ler dados de um arquivo usando o fread , que lerá os
dados de um arquivo em um local da memória e retornará o número de itens lidos com êxito do
arquivo.
Testando
Execute o seguinte comando para avaliar a exatidão do seu código usando check50 . Mas
certifique-se de compilar e testar você mesmo!
check50 cs50/problems/2021/x/recover
style50 recover.c
Anterior
Próximo
https://ead.napratica.org.br/enrollments/7235444/courses/84414/course_contents/2169400 5/5