CSI Lab 15
Tuesday, April 29th
"I'll take potpourri for $400 Alex."
The lab with a little bit of everything
Introduction
Yesterday's lecture (session 38) introduced the concept of steganography. We
introduced two different versions of "Encoder"
- Write the ord() value of each char into the red channel of the
corresponding pixel. Thus, if the text file was 200 characters long, the
first 200 pixels in the photo had their red channel changed (sometimes
dramatically).
- Split the ord() vlaue of each char into its 100s part, its 10s part, and
its 1s part. Thus, the letter 'j', whose ordinal value is 106, would get
split into 1, 0, and 6. We modified the ones value of each rgb channel
to equal these three values respectively. Thus, if a pixel with color
0,0,0 was trying to hide the letter j, it would change to 1,0,6. If a
pixel with color 123,52,17 was trying to hide the letter j, it would change to
121,50,16.
In both cases, we used character NULL (whose ordinal value is 000) to encode
the EOF (end of the file)
Today, I want you to decode some secret messages.
Activity A : Decoding a message hidden with simpleEncode()
Download:
Write a method called simpleDecode(picture,filename). This method
should:
- use filename (assumed to be a COMPLETE path to an existing text file) to
open up a text file for writing. Note that we will erase whatever might
have originally been in filename in this process.
- iterate over pixel in the Picture ...
- ... getting the red component ...
- If this value is non-zero than this is assumed to be a character so the
value is cast to a char and then written to the text file.
- If the value is equal to zero than this is assumed to be the EOF signal.
The output file should be closed immediately and all further pixels ignored.
To test your method use the picture above. If everything is working
properly you should be able to read one of my favorite short-stories in the
output file that you selected.
Activity B : Decoding a message hidden with complexEncode()
Download:
Write a method called complexDecode(picture,filename). This method
should:
- use filename (assumed to be a COMPLETE path to an existing text file) to
open up a text file for writing. Note that we will erase whatever might
have originally been in filename in this process.
- iterate over pixel in the Picture ...
- ... getting the ones value of each of the red, green, and blue components
...
- These three single digit numbers are reassembled by making the red the
100s value, green the 10s value, and blue the 1s value
- If this this new combined value is non-zero than this is assumed to be a
character so the value is cast to a char and then written to the text file.
- If the value is equal to zero than this is assumed to be the EOF signal.
The output file should be closed immediately and all further pixels ignored.
To test your method use the picture above. If everything is working
properly you should be able to read the study guide for the final exam.
Activity C : Yet ANOTHER way to encode pictures
In lab last week, and in the two days of lecture that followed, we wrote
pictures as text files by worrying about colors of individual pixels. Even
in the work we did on Friday (session 37)
we were interested in pixel by pixel color. These techniques of storing
and regenerating graphics are referred to as raster techniques or
raster graphics.
But if you consider my simple XKCD comic strip:

You know that I didn't "draw" it pixel by pixel. I drew it by creating
a series of "geometric objects" The characters head wasn't treated as
several hundred individual pixels, but instead as a single geometric shape.
Graphics techniques that are based on creating images through these "shape
based" techniques are referred to as
vector graphics.
If I wanted to treat the XKCD image above as a vector graphics application, I
would need to keep track of the geometric shapes that went into making the
larger image.
Consider the following text file:
This file is MUCH smaller than the either:
Write a method called readVectorCmds(filename). This method should:
- Take in a single parameter, a completely-formed filename in the style of
xkcd_vector.txt above.
- Open that file for reading
- Create an empty picture based on the dimensions in line 1 of that file
- Consider each of the remaining lines in the file...
- ... based on what command is indicated in the first part of the line, use
the parameters in the remainder of the line to generate that graphical object.
- When the file is done being read (and thus, the picture is drawn) it
should return the picture
The text file above should produce the comic above.
[Bonus] Activity D : Steganography with sound
Write a method called
simpleSoundEncode(sound,filename)
This method should:
- Take in a previously opened sound and...
- ... a well formed filename for a text file
- It should encode the text file in the Samples that make up the Sound in
such a way that the sound still retains the bulk of it's original sound.
- And then return this "new" sound
You may use any technique you like that largely preserves the
original sound. Thus, if I encode hamlet into the Dr. Guzdial reading the
preamble, I should be able to hear him reading the preamble the whole way
through and I don't want to hear a static hiss garbling the first 8+ seconds of
the sound. (How many samples would be used up if you did a STRAIGHT
replace one character per sound sample).