CS 111 - Program Design I


Due Date: Thursday, December 1, 2016, at 11:59 pm

This project will use a technique called "steganography" to encode a text message. Steganography is basically hiding one set of data within another set of data. Some decent discussions of this technique can be found at http://www.garykessler.net/library/steganography.html, http://windowsitpro.com/security/other-forms-steganography or http://en.wikipedia.org/wiki/Steganography

An example of steganography is the following message that might have been sent by cablegram from a spy during the First World War.


When only the first letter of every word is used, the following message is uncovered.

Or with spaces inserted
For this project, we want to take an ascii text message and hide it into the a sound file. We will also want to be able to extract the message. For this we will need to write one program that can either embed a text message into a sound or extract a message from a sound. Your program will first first prompt the user to enter the value of either 1 or 2.
  • If the user enters a 1, your program is to perform the embedding
  • If the user enters a 2, your program is to perform the extracting
Recall that a text message is a collection (i.e. encoding) of multiple ascii characters and each ascii character can be represented as a numeric value and (finally) each numeric value can be represented in a series of decimal digits (values from zero through nine). Thus the text message of "Welcome!" is made up of the ascii characters:
  • W
  • e
  • l
  • c
  • o
  • m
  • e
  • !
These ascii characters are represented with the following numeric values (in decimal):
  • 87
  • 101
  • 108
  • 99
  • 111
  • 109
  • 101
  • 33
The ascii values can be found at http://www.asciitable.com. We can easily compute the decimal ascii value of a character by using the python built in function of ord( ). Note that a character in python is a string of length 1.

      asciiValue = ord ('h') 

Hiding a Text Message in a Sound

The plan is to encode each of the ASCII values of the text message in the samples of the sound object. If a sound sample's amplitude value is only changed by a small amount, most people will be unable to notice the change. Since the ASCII values range from 0 to 127, which can be represented by 7 bits/wires on a computer. Each sample value will be changed by at most 128 out of 32767. This change is less than 0.4%. This change might be able to be heard but most likely it will just sound a bit "flat" and largely go unnoticed.

Initially, we will want all of the samples in the sound object to be "smoothed" out. This will result in every sample having its least significant 7 bits of its amplitude value set to zero. The way to do this is to determine the current value in the last 7 bits of the sample and subtract this value from the sample's amplitude value. The modulus operator can help us determine what value is stored in the last 7 bits of the sample's ampliture, simply just do the modulus operation, %, with a value of 128 as the second operand value.

      lsvalue = ampValue % 128
      modAmpValue = ampValue - lsvalue 

Once a sound file has been "smoothed", we will encode one ASCII character from the text message into each sound sample. Thus to encode a text message of 100 characters, we would need 100 sample amplitude values. At this rate, a one second sound sample can encode 22050 characters. At this rate, the longest books (like War and Peace) could be placed into sounds less than 4 minutes long.

To encode a ASCII character into a sound sample, we simply add the decimal value of the ASCII character (a value from 0 to nine127) to the "smoothed" amplitude value of the sound sample when the original amplitude value is positive.

The following table is to help us with this. It shows the first 8 samples from the file gettysburg10.wav. Note the sample values are relatively small numbers as this is only the first 1000th of the sound and nothing has been said yet.

  • The first column shows the sample index (note the first sample is "sample index zero").
  • The second column shows the original amplitude values from the sound.
  • The third column shows the amplitude values have they have been "smoothed".
  • The fourth column shows the ascii characters from the string Welcome!
  • The fifth column shows the ASCII values in decimal from the string: Welcome!
  • The sixth column shows the amplitude values with the decimal digits from the string added to it.

0 59 0 W 87 87
1 39 0 e 101 101
2 16 0 l 108 108
3 10 0 c 99 99
4 -1 -128 o 111 -17
5 7 0 m 109 109
6 -12 -128 e 101 -27
7 -7 -128 ! 33 -95

The problem with the above example is that since there is nothing being "said" during those samples, the sample values are all close to zero. Let us look as a different (more interesting) section of the sound.

12750 8018 7936 W 87 8023
12751 8993 8960 e 101 9061
12752 9671 9600 l 108 9708
12753 10061 9984 c 99 10083
12754 10276 10240 o 111 10351
12755 10364 10240 m 109 10349
12756 10462 10368 e 101 10469
12757 10180 10112 ! 33 10145

One we know the Character Number, we can get the character from the string by using the [ ] operator on the string. This operation will give use the character at that position. To get that ASCII Character code number for the character simply use the ord( ) function in python

Extracting the Text Message

To extract the text message from a sound file, we need to determine the ASCII value encoded at each sample value, convert the ASCII value to its corresponding character, and join the characters together into a string.

To extract the ASCII value encoded at each sample value, we just need to do the modulus operation by 128 on the sample value. This will give us the value from 0 to 127 that was added to the smoothed out value when the text was hidden in the sound.

To convert from the decimal ASCII value to the character, use the python chr( ) function. The following example will put a lower case a into the variable letter, since the 97th ASCII character is lower case a.

  • letter = chr(97)
We will assume that the number of samples in the sound greatly out numbers of ASCII characters that need to be hidden/extracted. Thus there will be a large number of samples that have been "smoothed out" but nothing added to them. All of these sample values will be multiples of 128 and will give a value of 0 when the extraction process in done. The ASCII value of 0 gives us the NULL character which can not be typed in by the user. Thus when we we encounter an ASCII value of 0 during the extraction process, we will stop the extraction process and display the string that has been created and then exit() the program.

Project Input and Output

To determine which portion of the program the user wants you to perform, use the requestIntegerInRange( ) function from the JES library.

For the encoding portion of the program, you are to prompt the user for a sound file to use and also prompt the user for the string to hide in the sound file. After the string is hidden in the sound, you are to prompt the user for a file to save the sound. You are to use the requestString() function from the JES library to get the string to hide. You are to use the pickAFile( ) function from the JES library to get the filenames for opening or saving the sound.

For the extracting portion of the program, you are to prompt the user for a sound file to use. You are to display the extracted string using the showInformation( ) functions from the JES Library. You are to use the pickAFile( ) function from the JES library to get the filenames for opening the sound.

Program Writing Style

Your program must be written using good programming style which includes:

  • Use of multiple functions
  • Good variable names
  • In-line commenting
  • Proper indentation of program statements
  • Use of blank lines to separate blocks of code.
  • Header block commenting for the program and each function written

    Your header block comment for the program must include the following:

    • Your Name,
    • Net-ID,
    • Course Name,
    • Assignment Name and
    • Day and time of your CS 111 lab section (i.e. Monday at 2:00)
    • A short description of the assignment.
Header block comments for each function must include the following:
    • A description of the purpose of the function
    • A listing of the name, type and purpose of every parameter
    • A description of the return value and its type

Project Collaboration

You are allowed to receive help on this project from other students who are also taking CS 111. Each student must still complete and submit his/her own project. You will be required to include a Collaboration Statement somewhere on your project if you receive help. This statement can simply be something like the following:

For this project, I received help from the following member of CS 111.

This statement should list each helping student's name in a comment in the "header comment" of your Java file that includes the main() function.

Submission of your Project

Submit your code via Blackboard.

Topic revision: r2 - 2016-11-14 - 18:59:52 - Main.troy
Copyright 2016 The Board of Trustees
of the University of Illinois.webmaster@cs.uic.edu
Helping Women Faculty Advance
Funded by NSF