15-123 effective programming in c and unix lab 5 – …ab/15-123s09/labs/lab5/writeup.pdf15-123...

6
15-123 Effective Programming in C and UNIX Lab 5 – Image Encryption with BMP Images Due Date: Saturday March 28th, 2009 by 11:59pm Background: Encryption is a method used to protect data from intruders during transmission. The idea of data encryption is to scramble data using a specific key, so attackers would need to know the key to decrypt the data. The reverse of data encryption is called decryption. Decryption algorithm will recreate the original data file. For example, a naïve encryption of an ASCII file is to encrypt each character just by adding 1 to each character. That is replacing each character by its successor in the ASCII table. So ‘a’‘b’ , ‘b’‘c’, …, ‘t’’u’. So the word “bat” would be encrypted as “cbu”. Now applying the decryption algorithm (or just subtracting one from each of the encrypted characters “cbu” or by replacing with its predecessor will produce the original word “bat”. Although there are number of research results available on image encryption, our goal in this assignment is not to use one of the more advanced algorithms, but try out number of simple algorithms, some of your choosing, that would allow us to work with binary files, do some bit manipulations, encode and decode image files. For simplicity we will consider only the uncompressed image formats like BMP (jpeg and gif are compressed forms of images). Here is some background information about BMP’s. The BMP file format: The images we are planning to encrypt are in the BMP file format, which is one of the most popular uncompressed file formats for images. Note that you will need to find a way to view the images for this assignment. I recommend writing and testing the program on Andrew Unix and using SSH File Transfer Client to view the files on the local machine using MS Paint to see if the encryption is working. If you are working on a Linux cluster machine, you can also use the command “display” ($ display image.bmp) to view the image assuming x terminal is installed. Your program should be able to encrypt any bitmap file of size n by m pixels. The actual size of a BMP image of n by m pixels is given by (3·n·m + 54+ some extra bytes) bytes. Each BMP file allocates 54 bytes for header information, and each pixel takes up 3 bytes for Red, Green and Blue (RGB). Extra bytes may be used for padding purposes. We should not encrypt the BMP header or the extra bytes. You should just read the first 54 bytes into an array, and when you write it out again, you should just write the header bytes unchanged. The pixels of a color image are stored in RGB format, which means that each pixel is represented by three bytes, one for red, one for green, and one for blue. One byte can store numbers in the range 0-255. So the color red is (255, 0, 0) and green is (0, 255, 0). And (128, 0, 0) make dark red, and (255, 0, 255) makes purple since purple is red + blue. It is important to note that the pixels are stored from left to right and from bottom to top (upside down!). So the first m groups of three bytes (3·m bytes) in the file (after the 54-byte header) correspond to the bottom row of the image, and the last m groups of three bytes correspond to the top row. Also make sure that you figure out whether image has extra bytes or not.

Upload: phungliem

Post on 09-Mar-2018

218 views

Category:

Documents


2 download

TRANSCRIPT

15-123 Effective Programming in C and UNIX

Lab 5 – Image Encryption with BMP Images

Due Date: Saturday March 28th, 2009 by 11:59pm

Background: Encryption is a method used to protect data from intruders during transmission. The idea of data

encryption is to scramble data using a specific key, so attackers would need to know the key to

decrypt the data. The reverse of data encryption is called decryption. Decryption algorithm will

recreate the original data file. For example, a naïve encryption of an ASCII file is to encrypt each

character just by adding 1 to each character. That is replacing each character by its successor in

the ASCII table. So ‘a’→‘b’ , ‘b’→‘c’, …, ‘t’→’u’. So the word “bat” would be encrypted as

“cbu”. Now applying the decryption algorithm (or just subtracting one from each of the

encrypted characters “cbu” or by replacing with its predecessor will produce the original word

“bat”. Although there are number of research results available on image encryption, our goal in

this assignment is not to use one of the more advanced algorithms, but try out number of simple

algorithms, some of your choosing, that would allow us to work with binary files, do some bit

manipulations, encode and decode image files. For simplicity we will consider only the

uncompressed image formats like BMP (jpeg and gif are compressed forms of images). Here is

some background information about BMP’s.

The BMP file format: The images we are planning to encrypt are in the BMP file format, which is one of the most

popular uncompressed file formats for images.

Note that you will need to find a way to view the images for this assignment. I recommend

writing and testing the program on Andrew Unix and using SSH File Transfer Client to view the

files on the local machine using MS Paint to see if the encryption is working. If you are working

on a Linux cluster machine, you can also use the command “display” ($ display

image.bmp) to view the image assuming x terminal is installed.

Your program should be able to encrypt any bitmap file of size n by m pixels. The actual size of

a BMP image of n by m pixels is given by (3·n·m + 54+ some extra bytes) bytes. Each BMP file

allocates 54 bytes for header information, and each pixel takes up 3 bytes for Red, Green and

Blue (RGB). Extra bytes may be used for padding purposes. We should not encrypt the BMP

header or the extra bytes. You should just read the first 54 bytes into an array, and when you

write it out again, you should just write the header bytes unchanged. The pixels of a color image

are stored in RGB format, which means that each pixel is represented by three bytes, one for red,

one for green, and one for blue. One byte can store numbers in the range 0-255. So the color red

is (255, 0, 0) and green is (0, 255, 0). And (128, 0, 0) make dark red, and (255, 0, 255) makes

purple since purple is red + blue. It is important to note that the pixels are stored from left to

right and from bottom to top (upside down!). So the first m groups of three bytes (3·m bytes) in

the file (after the 54-byte header) correspond to the bottom row of the image, and the last m

groups of three bytes correspond to the top row. Also make sure that you figure out whether

image has extra bytes or not.

The form of a bit map image are given as follows.

You can simply think of the file structure as

The left most RGB is the lower right pixel of the image and last RGB is the upper left pixel of

the image.

Suggested Data Structure: We really do not need any special data structure to do this program. Just a simple array of

characters is good enough to store all the bytes in the file. However, maintaining some of the

image attributes in a struct such as

typedef struct {

char* data;

char* header;

int height;

int width;

int size;

} Bitmap;

will help us perform the necessary operations on the image. For example, we can invert the

image or shift pixel rows of the image etc. The data field inside the bmp struct will contain the

array of bytes that make up the image. The header field will contain the header information and

will not change in any operations. Each field requires allocation of dynamic memory as needed.

The structure of the 54 byte header of a BMP file is as follows. The first 14 bytes are allocated

for

Header – 54 bytes | R G B R G B R G B extra bytes

typedef struct {

unsigned short int type; /* BMP type identifier */

unsigned int size; /* size of the file in bytes*/

unsigned short int reserved1, reserved2;

unsigned int offset; /* starting address of the byte */

} HEADER;

The next 40 bytes are reserved for a structure as follows.

typedef struct {

unsigned int size; /* Header size in bytes */

int width,height; /* Width and height in pixels */

unsigned short int planes; /* Number of color planes */

unsigned short int bits; /* Bits per pixel */

unsigned int compression; /* Compression type */

unsigned int imagesize; /* Image size in bytes */

int xresolution,yresolution; /* Pixels per meter */

unsigned int ncolors; /* Number of colors */

unsigned int importantcolors; /* Important colors */

} INFOHEADER;

The Assignment In this assignment we plan to complete number of functions so that we can read, write, encrypt

and decrypt images.

Part 1 – In this part of the assignment you are simply trying to read, store and write a BMP

image file. You are to complete the following functions.

//Read the image into mybmp. You must allocate just enough memory to hold the

image bytes. This can be done by first reading the header and figuring out

what the size of the image is

void readImage(char* infile, Bitmap* mybmp);

// writes the encrypted image to outfile

void writeImage(char* outfile, Bitmap* mybmp);

You also need to complete the main program so that when the command $ ./lab5 file1 file2

It will simply read BMP file1 and write to BMP file2. When you open file2 using an image

viewer, you should see the same image as in file 1. This will allow us to make sure, we can read

and write BMP images.

Part 2 – In this part of the assignment you are to write a “non-trivial” encryption algorithm to

encrypt your image. You should also write a decryption algorithm to recover the original image.

See “Suggested Algorithms” area below to see some suggestions. A “trivial” algorithm is one

that just negate the bits or uses a flag to mask the bits. A non-trivial algorithm will try to distort

the image while keeping some attributes.

You are to write at least the following functions: // encrypt the image using a non-trivial algorithm.

void encrypt(Bitmap* mybmp);

// decrypt the image. You are free to use the inverse of the encrypt

void decrypt(Bitmap* mybmp);

You also need to complete the main program to handle “-e” and “-d” flags $ ./lab5 –e file1 file2 //encrypt file1 and write to file2

$ ./lab5 -d file2 file1 // decrypt file2 and write to file1

Part 3 – In this part of the assignment you are to write a simple rotate function that will rotate

the current image by 180. This is not difficult if you really think about how the image is stored.

//rotate makes the image upside down or rotation by 180 degrees

void rotate(Bitmap *bitmap);

You also need to complete the main program to handle “-r” flags $ ./lab5 -r file1 file2 // rotate file1 and write to file2

Part 4 – In this part of the assignment you are to implement a known algorithm that allows us to

hide a message inside an image. Steganography is the art and science of writing hidden messages in

such a way that no-one, apart from the sender and intended recipient, suspects the existence of the

message, a form of security through obscurity[source: Wikipedia]

In this part we will only test the following two images. //This will apply the following algorithm to an image. Remove all but last

two bits of each color component. Make the resulting image 85 times brighter

void coolAlgorithm(Bitmap* mybmp);

This algorithm will take this image

and convert to this image when you apply the above algorithm. That is, remove all but last 2 bits

of each color component. Then multiply (or bit shift) the color component by 85.

[source: Wikipedia]

You also need to complete the main program to handle “-r” flags $ ./lab5 -c file1 file2 // tree is converted to a cat –really cool!!

Style Points Proper use of functions (passing/returning arguments etc), commenting, style, handin, compile,

indenting, and efficiency of the solution are worth an additional 10 points.

Algorithms for Part 2: You need to use a “non-trivial” algorithm to decrypt the bytes of the file. A trivial algorithm is

one that negates each bit of the image. The decryption algorithm then will negate the bits again

to get the original image back. Here is what happens to Prof. Guna when we applied that

algorithm to his image.

Here is a series of other encryption algorithms by manipulating the color depth of the original

image.

Be creative and come up with an encryption algorithm that does something really cool (like

complete distortion). Ideally, after you apply your encryption algorithm, we should not be to tell

what the original image was but has a shadow of the image.

Shifting the bit patterns to encrypt may not be a good idea. Be careful! You encryption algorithm

cannot afford to lose any bits! Masking is a good way to turn off some bits and then unmasking

can recover those bits. We will discuss masking techniques in class. Here are some more

examples of encrypted images using a simple mask:

More examples

Running the program: Use the Makefile to test your program. Your program should run by typing files names and

command line options as follows. $ ./lab5 –e file1 file2 //encrypt file1 and write to file2

$ ./lab5 -d file2 file1 // decrypt file2 and write to file1

$ ./lab5 -r file1 file2 // rotate file1 and write to file2

$ ./lab5 -c file1 file2 // apply cool algorithm

Extra Credit: There is some opportunity to get extra credit in this assignment. TA’s will

consider giving up to +5 points for really cool algorithms. You should write why it is a really

cool algorithm in a readme.txt file in the handin folder. For more advanced users, you can also

think of how to implement an “edge detection” algorithm. Edges can be detected, in theory, by

observing changes in depth of color intensity, variations in scene illumination, change in material

properties etc. Your algorithm can generalize to images say, passport images of people, so you

can mark the outline. If you are completing this part, give a link to an image folder you tested

with so TA’s can try things out. Mark the outline with a red pixels.

Commenting your code: Please comment your code to show what you are doing. The least

amount of comments is a short description at the beginning of each function that explains what it

does, what parameters it takes, and what the expected output or return value is.

Downloading your code: You can download code from

/afs/andrew.cmu.edu/course/15/123/downloads/lab5

All updates will be available from FAQ.txt from the Bb

Submitting your code: submit main.c to /afs/andrew/course/15/123/handin/lab5/yourid. DO

NOT submit any image files you are using to test the program.