본문 바로가기

U of T: Computer Science/First Year: CSC108

CSC108 Assignment 3

CSC108H/A08H Assignment 3: A Poem in a Picture

Overview

The purpose of this assignment is to give you practice in the following areas:

  • working with images and text files,
  • using while loops and nested lists, and
  • testing.

Preface

A year ago, it was, when your friend fell in love. Alas, your friend's significant other comes from a strict family, and all their emails and correspondence are monitored. Your friend is distraught; they want to write a series of love poems, but they know that the parents will probably find them.

Luckily, you've just received an assignment for your intro programming course that will solve all their problems: this assignment has you write two functions: one that will hide some text inside a picture and another to extract that text. Someone can hand the extracting program to your friend's sweetheart, and then your friend can send seemingly innocuous pictures that contain hidden passionate poems, and the parents will never know.

Part 1: Warm-up exercise

This part involves tasks related to the rest of the assignment. These functions may be used as helper functions in Part 2. Save these functions in a file called warmup.py.

Function Name Description
get_hundreds(int) Given a positive integer less than or equal to 999, return the hundreds value (as an int).
get_tens(int) Given a positive integer less than or equal to 999, return the tens value (as an int).
get_ones(int) Given a positive integer less than or equal to 999, return the ones value (as an int).
read_file(file) Given a file, return the file contents (as a str).
write_file(file, str) Given a file and a message, write the message to the file.
get_mapping(file) Given a file that contains one character, a space, and a 3-digit number per line, return a nested list that has one element for each line of the file, where each element is itself a list with the character as the first element and the 3-digit number as the second (both strs). Here is a sample file.

Part 2: Steganography

According to Wikipedia, steganography "is the art and science of writing hidden messages in such a way that no one apart from the intended recipient knows of the existence of the message; this is in contrast to cryptography, where the existence of the message itself is not disguised, but the content is obscured. Quite often, steganography is hidden in pictures."

A Steganography Method

In this assignment, you will use a steganography method to hide a text message in an image. Although you will be modifying the image, the image will not look any different to the naked eye:

Hiding a message in an image

As you know, an image is made up of pixels, and each pixel has three color components: red, green, and blue. Each of the color components has a value between 0 and 255 (inclusive). To hide the message, each character will be hidden in a pixel. This will be done by slightly modifying the three color values for that pixel.

To begin, we will represent each character using a three-digit number. The mapping of characters to three-digit numbers will be based either on an existing mapping called the American Standard Code for Information Interchange (ASCII) or on a user-provided mapping (a text file with one character, a space, and a 3-digit value per line). The rest of this example uses the ASCII mapping, but the same method can be used with any user-provided mapping.

The ASCII value of 'k' is 107 (we get this value using built-in function ord). The ASCII values of some characters are only two digits, such as the ones for 'A' and ' ', which are 65 and 32, respectively. We'll add a zero to the front to turn them into three-digit numbers: 065 and 032.

Now when we want to hide a character in a pixel, we will actually hide its ASCII value in the color values of the pixel. For example, let's hide 097 (the ASCII value of 'a') into a pixel with RGB values of 194, 191, and 184. To hide the value 097, we replace the last digit of each of the three RGB values with the values 0, 9, and 7, respectively.

Embedding an ASCII value in a pixel.

To decode the message, we examine each pixel and extract the last digit of each color value to form the ASCII value of the character. We then convert the ASCII value to the character (using built-in function chr).

Extracting an ASCII value from a pixel.

Notice that when the message is revealed, the pixel is not modified, so the image is not converted back to its original form.

Note that this method fails if any of the RGB values are greater than or equal to 250. If we try to hide 097 in a white pixel (RGB values 255, 255, 255), we'll get an error, since 259 is not a legal value for the green component of the pixel. How you resolve this is your decision: multiple possible solutions exist, each with some advantages or disadvantages, and you must select one. We leave it to you to evaluate the options, implement one solution, and then document and justify your decision (in Part 3).

The Task

Your task is to implement the following functions:

Function Name Description
hide(Picture, str, list=[]) Given a Picture and a text message, hide the message in the Picture using the steganography method described above and return the modified Picture. The third parameter is optional; if it is not specified, then the message should be hidden using the ASCII mapping. If the third parameter is specified, it is a mapping: a list of lists where each element is a 2 item list containing a character and its corresponding 3 digit value (both strs).
reveal(Picture, list=[]) Given a Picture with a message hidden in it, use the steganography method described above to extract the message from the image and return the message (as a str). The second parameter is optional; if it is not used then the message was hidden using the ASCII mapping. If the second parameter is used, it is a mapping: a list of lists where each element is a 2 item list containing a character and its corresponding 3 digit value (both strs).
embed_message(list=[]) Usepick_a_file to get a text file containing a message to hide
and to get a picture to contain the message.
Read the text file and make the picture, and then
call the hide function to embed the message using
the given mapping. Return the resulting picture.
 (You do not need to write nose tests for this function, as it is interactive.)

Note that you are not expected to have all your code inside these functions alone. These are the major functions, which should call other, helper functions - possibly some from your warmup module or other functions that you write yourself. Whenever you find that your code seems to be doing the same task again and again, that task should probably be in a function of its own. The marking scheme places some weight on this. If you are using functions from warmup, you should of course import them from warmup.

Testing

To determine that the functions in your steganography module work correctly and to debug them (uncover and fix problems with them), you need to test them. Every time you write a function for your steganography module, you should also write test functions for it in your test_steganography module. Do not write large chunks of code without testing them. Run your collection of tests frequently to make sure that everything continues to works correctly.

Your task is to use nose to write a test module called test_steganography. We are providing starter code for the module. The starter code contains a function encodes that checks if a character has been properly encoded into a pixel and a description of how to test.

Make sure that your test module adheres to the following principles:

  • Your test module (test_steganography) should contain at least one test function to test each function in your steganography module except for embed_message. (You do not need to include nose tests for embed_message since it is interactive.)
  • The more interesting a function is, the more test cases you should have for it. What makes a function "interesting" can be the number of interesting combinations of inputs that function can have, the number of different results that the function can have when run several times, and so on.
  • Test the more basic functions early in your tester module, and then move on to more complex ones. (An analogy: make sure that the car parts work on their own before you take the whole car for a test drive.)
  • Don't try to test too many things in a single test case. Each test case should test only a couple of conditions.
  • It is a good idea to place each assert in a separate test_... function, since nose stops evaluating the function as soon as one of the asserts fails. If one or more asserts that come later would also fail, we never find out: they don't get executed.
  • Document each test case: include a description of what is being tested (e.g., assert blah, "description of test case").
  • Avoid duplicate tests: make sure that each test case is testing something different. Don't write 10 tests when 2 would do. (Marks will be deducted for duplicate test cases.)

Part 3: Written Evaluation of Design Decisions

To complete this assignment, you will need to make some design decisions, such as:

  • for color values 250-255, how digits 6 and up are hidden and revealed, and
  • how the length of the message is indicated so that the reveal function can determine where it ends.

For each of the design decisions above, write a short paragraph (approximately 125 words each) describing:

  • at least two options for addressing the issue,
  • the option that you chose, and
  • the reasoning behind/consequences of your choice.

Submit this part in a plain text file named design.txt. To guarantee that the file is plain text, you should use Wing as your editor. If you don't use Wing and we can't read your file, then we will not mark your writing component. Please leave a blank line between paragraphs.

What to Hand In

Hand in the following files:

  • warmup.py
  • steganography.py
  • test_steganography.py
  • design.txt
Student's Solution

Teacher's Solution

'U of T: Computer Science > First Year: CSC108' 카테고리의 다른 글

CSC108 Project  (0) 2007.12.16
CSC108 Assignment 4  (0) 2007.12.16
CSC108 Assignment 2  (0) 2007.12.16
CSC108 Assignment 1  (0) 2007.12.16
CSC 108 Course 소개.  (0) 2007.12.16