CS 101 - Introduction to Computing, Fall 2008

Project 4 - Hiding a Text Message in a Sound

Due Date: Thursday April 29, 2010 at 11:59 pm

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 two program: Proj4a.java and Proj4b.java. Where Proj4a.java will place the message into a sound file and Proj4b.java will extract the message from the sound file.

Recall that a text message is a collection (i.e. encoding) of multiple ascii characters and each each ascii character can be represented as a numeric value and (finally) each numeric value can be represented in a series of one's and zero's (a binary number). Thus the text message of "Hi!" is made up of the ascii characters:

These ascii characters are represented with the following numeric values (in decimal): These values in binary are:

Hiding a Text Message in a Sound

The plan is to encode each binary digit of the binary number in a sample of the sound object. An even value for the sound sample implies the binary digit zero. An odd value for the sound sample implies the binary digit one.

Initially we will want all of the samples in the sound object to be "evened" out. This will result in every sample having an even value. The way this is to be done is if the sample value is even, leave it unchanged. If the sample is odd, subtract one from the value to make it even. It is important that we subtract one because of the range of values the sound samples could have (the largest possible value is odd, while the smallest possible value is even).

Note that changes of a sample value by a value of one will have no impact to the sound quality on the human ear. Actually it is changes of values around 10 that begin to be detected by the human ear.

Once a sound file has been "evened", we will encode one binary digit from the text message into each sound sample. Since each ASCII character is considered to have 8 binary digits, we will need 8 sound values for each ASCII character. Thus to encode a text message of 100 characters, we would need 800 sound values. At this rate, a one second sound sample can ecnode 2762 characters.

To encode a binary digit into a sound sample, we simply add the binary digit (a value of one or zero) to the "evened" value of the sound sample. The result sound sample will be even when the binary digit was zero and odd when the binary digit was one.

The following table is to help us with this. It shows the first 24 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 stated yet.

Sample
Number
Original
Sample
Value
"Evened"
Sample
Value
ASCII
Characters
Decimal
Values
Binary
Digits
Binary
Digit
Position
Final
Sample
Values
05958H720058
139380138
216160216
310101311
4-1-204-2
576056
6-12-1216-11
7-7-807-8
81010i1051011
925240124
1061600260
1157561357
1246460446
1341401541
1443421643
1573720772
167676!331077
1760600160
1846460246
1939380338
2031300430
2126261527
2235340634
2337360736

To determine which binary digit of which character is associated with which sample from the sound object, use the following where sampleIndex is the index of the SoundSample from the sound object:

One we know the Character Number, we can get the character from the string by using the charAt() method of the String class. This method will give use the character at that position. To get that ASCII Character code number for the character simply store the character into a variable of type integer.

To get the bit value (zero or one) for a particular Binary Digit Position from the ASCII character code number, we should write a method with the following method description:

public static int getBinaryDigit (int asciiCode, int BinaryDigitPosition)
{
  // This method should divide the asciiCode by 2 as many times
  //   as specified by the BinaryDigitPosition, 
  // Then use the modulus operator % to find the remainder 
  //   of a division by 2.
  // This remainder value is the bit value that we want returned
  //   by the method.


}

Extracting the Text Message

To extract the text message from a sound file, simply determine whether a sound value has an even or odd value. When the value is even, the text message has a binary digit of zero. When the value is odd, the text message has a binary digit of one.

Once the bit values are known we need to build them together into characters and then join the characters into Strings. To build the 8 bits into a ascii character code number, we start with a variable for the ascii code that initially has a value of zero. For every BinaryDigitPosition with a value of one, we take another variable which is initial set to one and multiply it by 2 the number of times as the BinaryDigitPosition. We then take the result and add it to the variable for the ascii code. We can actually ignore any bit values of zero. Once we have done this for all the 8 bit values, we can store this integer value into a character variable. Once the character value is know, we can concatenate the character to the end of a string.

For example, assume we needed to get the character i. The 8 bits and the coorsponding BinaryDigit positions would be:

ASCII
Characters
Decimal
Values
Binary
Digits
Binary
Digit
Position
i10510
01
02
13
04
15
16
07

First, we intialize the asciiCode to zero.

Then, we look at BinaryDigitPosition 0 and see we have a value of 1.
We then multiple a value of 1 by two zero times for a result of 1.
We add 1 to the asciiCode value for a new value of 1.

Then, we look at BinaryDigitPosition 1 and see we have a value of 0 so we ignore it (i.e. we don't change the value in asciiCode).

Then, we look at BinaryDigitPosition 2 and see we have a value of 0 so we ignore it (i.e. we don't change the value in asciiCode).

Then, we look at BinaryDigitPosition 3 and see we have a value of 1.
We then multiple a value of 1 by two three times for a result of 8.
We add 8 to the asciiCode value for a new value of 9.

Then, we look at BinaryDigitPosition 4 and see we have a value of 0 so we ignore it (i.e. we don't change the value in asciiCode).

Then, we look at BinaryDigitPosition 5 and see we have a value of 1.
We then multiple a value of 1 by two five times for a result of 32.
We add 32 to the asciiCode value for a new value of 41.

Then, we look at BinaryDigitPosition 6 and see we have a value of 1.
We then multiple a value of 1 by two three times for a result of 64.
We add 64 to the asciiCode value for a new value of 105.

Then, we look at BinaryDigitPosition 7 and see we have a value of 0 so we ignore it (i.e. we don't change the value in asciiCode).

The final value of asciiCode is 105, which is the proper ASCII code value for the character i.

We will assume that the number of SoundSamples greatly out numbers of number bits that need to be hidden/extracted. Thus there will be a large number of SoundSamples that have only even values in them. While doing the extraction if we encounter a character that was created from 8 sound samples with even values, we would have extracted ASCII Character 0 or the NULL character. When this occurs, we will stop the extraction process and display the string that has been created.

Project Input and OutPut

For the encoding program, Proj4a.java, 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 may use the SimpleInput.getString() method to get the string to hide.

For the extracting program, Proj4b.java, you are to prompt the user for a sound file to use. You are to display the extracted string using one of the methods from the SimpleOutput class.

Project Collaboration

You are allowed to receive help on this project from other students who are also taking CS 101. 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 101.
This statement should list each helping student's name in a comment in the "header comment" of your Java file that includes the main() method.

Submission of your Project

Submit your code via Blackboard.

CS 101 Home Page
Department of Computer Science
University of Illinois at Chicago