Showing posts with label encode sound file. extract sound file. Show all posts
Showing posts with label encode sound file. extract sound file. Show all posts

Tuesday, May 8, 2012

Hiding a Text Message in a Sound 'java"

//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.
//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 encode 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 encoding.


/**
*/
public class Project

{

public static void main(String[] args) {
// Ask user for what to do
int select = SimpleInput.getIntNumber("what would you like to execute?\n\n1: Encrypt a text message into sound\n2: Extract a text message from a sound");
if (select == 1) {
// Hide The Message
String inputFile = FileChooser.pickAFile();
// prompt user for a file
String message = SimpleInput.getString("Type the message you want to hide in the sound file:");
String outputFile = SimpleInput.getString("Filename of modified sound: ");
encodeSound(inputFile, outputFile, message);
// Encrypt message in inputFile and save it to outputFile
} else if (select == 2) {
// get the hidden text message from file
String inputFile = FileChooser.pickAFile();
decodeMessage(inputFile); // Decode the message in inputFile
} else {
System.exit(1); // Exits if any other digit is input
}
}

// Hides a text message in a sound file.
public static void encodeSound(String inputFile, String outputFile, String message)
{
// Create the sound file
Sound s = new Sound(inputFile);
int nbrOfSamples = message.length() * 3;
// Calculate the number of samples needed for the message including the terminating null character
smoothAmpValues(s, nbrOfSamples + 3);
// Set the one's of the amplitude values to zero.

for (int g = 0; g < nbrOfSamples; g++) {
// Iterate over all samples needed
int asciiValue = (int) message.charAt(g / 3);
// Acquire ascii value for the current character
int digit = getDecimalDigit(asciiValue, g % 3);
// Acquire next digit to encode
int ampValue;
if (s.getSampleValueAt(g) >= 0)
{
// If amplitude is positive
ampValue = s.getSampleValueAt(g) + digit; // then add new value
}
else
{ // If amplitude is negative
ampValue = s.getSampleValueAt(g) - digit; // then subtract new value
}
// Special cases
if (ampValue > 32767)
{
ampValue = ampValue - 10;
}
if (ampValue < -32768)
{
ampValue = ampValue + 10;
}

s.setSampleValueAt(g, ampValue); // Replace amplitude value in the sound object
}
try {
s.writeToFile(outputFile+".wav");
// Save the encoded sound file
} catch (SoundException e) {
e.printStackTrace();
}
System.exit(0);
// Exit program
}

// start a method to set the one's didgit in the frst sample to zero.
public static void smoothAmpValues(Sound s, int nbrOfSamples)
{
for (int g = 0; g < nbrOfSamples; g++) {
int ampValue = s.getSampleValueAt(g);
int modAmpValue = ampValue - ampValue % 10;
// Set one's digit to zero
s.setSampleValueAt(g, modAmpValue);
// Replace amplitude value in sound object
}
}

// start a method to get certain digit from an integer (asciicode =)
public static int getDecimalDigit (int asciiCode, int decimalDigitPosition) {
for (int i = 0; i < decimalDigitPosition; i++) {
asciiCode = asciiCode / 10;
}
return Math.abs(asciiCode % 10);
}

//start a method to decode the message.
public static void decodeMessage(String filename) {
Sound s = new Sound(filename);
// Create sound file
SoundSample[] samples = s.getSamples();
// Acquire the samples from the sound file
int[] digit = new int[3];
// collection containing the three digits of an ascii code
String message = "";
int sampleIndex = 0;
boolean nullReached = false;

while (!nullReached) {
digit[0] = getDecimalDigit(samples[sampleIndex].getValue(), 0); // Acquire the digits
digit[1] = getDecimalDigit(samples[sampleIndex + 1].getValue(), 0);
digit[2] = getDecimalDigit(samples[sampleIndex + 2].getValue(), 0);
int asciiValue = digit[0] + digit[1] * 10 + digit[2] * 100; // and change to the ascii code

if (digit[0] == digit[1] && digit[1] == digit[2] && digit[2] == 0)
// Exit if null character is reached
nullReached = true;
message += (char) asciiValue;
// Attach the next hidden character to the message string
sampleIndex += 3;
if (sampleIndex > samples.length - 1) {
// Print error message and end program if null character is never reached
SimpleOutput.showError("Null character never reached. Possible reason: no hidden text in file.");
System.exit(1);
}
}
SimpleOutput.showInformation(message); // Display the hidden message.
System.exit(0);
}

}