Question: Assignment: Steganography Instructions You'll be writing 4 classes: a class named Steganography with static methods for encoding and decoding secret messages, 2 new exceptions type,
Assignment: Steganography
Instructions
You'll be writing 4 classes: a class named Steganography with static methods for encoding and decoding secret messages, 2 new exceptions type, and a driver containing main. Here's a description of what should be in them:
NotEnoughSpaceException
This class inherits from exception. Its message should indicate how much space was needed, and how much is available. It should just contain one constructor that takes the size information as parameters and calls the Exception constructor to set the message appropriately.
SecretMessageException
This exception will be thrown when there's an error decoding the message. This means either the input file doesn't exist, or there's no secret message there (probably causing you to try to seek() outside of the file). It should contain a constructor that takes a String message parameter.
Steganography
This class will contain 3 static methods:
public static int[] getDataLocations( int start, int stop, int numLocations) throws NotEnoughSpaceException
This method returns an array that indicates where each character in the message should be stored. For each character, you'll need enough space to store the character itself, and an integer representing where the next character is (how many bytes total will that be?). Start and stop indicate the first and last bytes that can be used. If there's not enough room to store all the bytes, this method should throw a NotEnoughSpaceException.
You can use whatever approach you'd like for this method, provided that there is space between each location. The first location should be equal to start.
A simple solution is to place all the locations as far apart as possible (find the maximum distance you can fit between each one and place them equidistantly far apart). Choosing locations randomly is another approach, but requires some care so that the locations don't cause overlaps. Do not bunch all the data together. It'll make it obvious that we're hiding a secret message and will be very noticeable if we play back the audio file.
public static String decodeMessage(File inputFile) throws SecretMessageException
This method will open an input file and return the secret message hidden inside. If this fails for any reason, you should throw a SecretMessageException (this means you should use a try/catch block, and inside of your catch block, you will throw a SecretMessageException with an appropriate message).
You'll make use of the RandomAccessFile class and its seek(), readChar(), and readInt() methods for this method. Hint: the String class has a constructor that takes an array of chars.
To test this method, see if you can read the secret message in this file: encoded-1.wavClick to view undefined. You should also be able to play the file with an audio player and it won't be obvious that there's a hidden message.
public static void encodeMessage(File inputFile, File outputFile, String message) throws Exception
This method performs the following operations:
make a copy of inputFile, and save it in outputFile. You'll want to make use of the static copy() method in the Files class. File objects have a toPath() method that may be useful for this as well.
compute where to put the data in the file (use your getDataLocations method here). Remember, the first 50 bytes should not be touched. Immediately after that, we'll write the size of the message, so where will the hidden message stuff be written?
write the secret message in the file. Again, this will involve the RandomAccessFile class and its seek(), writeInt(), and writeChar() methods.
The encodeMessage method can pass the buck on errors (it can use a generic "throws Exception" clause at the top and can return immediately if any exceptions are thrown).
Driver
The driver should ask the user to enter a message, then write the secret message to a file, read the secret message back from the file, and verify that it matches. Make sure that you create a NEW file that you hide the message in, and don't overwrite the old one. Here is the original version of the .wav file from above that you can use to test with: name.wav
textlength of first message letter (int index of next a letter index of Header, 50 bytes (char) next (char) (int) (int)
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
