我正在准备一个隐藏音频文件中文本文件的程序。编码工作正常,但不是解码。首先,我有一个in.txt(包含文本)文件,它将把它隐藏在一个音频文件(.wav,(16位44.1kHz)中,以获得一个音频编码文件。在解码中,我应该让audioencoded文件提取消息到out.txt。
我的问题是,因为我得到了out.txt文件,但文本不在其中(它的大小为1Ko,就像in.txt一样)。但是当我打开它时,我没有看到提取的文字。
这是我的代码:
public static void main (String [] args) {
Scanner scan = new Scanner(System.in);
int maxChar = 40000;
System.out.println("What would you like to do? (enter the number)");
System.out.println("1 - Encode a text file into an audio file");
System.out.print("2 - Decode an audio file(you will need the key) ");
int command = scan.nextInt();
System.out.println();
if (command == 1) {
char [] contents = new char[maxChar]; // Initialize an array of characters to read the text file into
System.out.print("Enter text file name that you want to encode (must be a plain text file) : ");
String textToEncode = scan.next(); // The text file to read in
if (!textToEncode.endsWith(".txt")) // Check if the filename ends with .txt and add the extension if it doesn't
textToEncode += ".txt";
File file = new File(textToEncode);
try {
Scanner s = new Scanner(file,"UTF-8");
s.useDelimiter("\\Z");
if(s.hasNext()) {
contents = s.next().toCharArray();
}
// The \\Z delimiter in combination with .next() will read input until there isn't any left
//System.out.println(contents);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("Enter the audio file name that you want the text encoded into (must be a .wav file)");
System.out.print("or if you want a generated clip of static, type \"1\" : ");
double[] audioFile = getAudioFile(scan.next());
/* DEBUG
System.out.println("Audio File before data written");
for (int p = 0; p < 100; p++) {
System.out.print(audioFile[p] + " ");
} System.out.println();
*/
int audioCounter = 0; // an extra counter for the audio file since its values cap at 1.0 and data would be lost if we tried adding the text to those points. The extra counter allows us to skip over those points.
for (int i = 0; i < contents.length; i++) {
while ((audioFile[i+audioCounter] + (double)(contents[i])/10000.0) >= 1.0) {audioCounter++;} // Increments audioCounter if the encoding would make the value at that point go above 1.0
audioFile[i+audioCounter] += ((double)(contents[i]))/10000.0;
}
System.out.println("Audio File after data written");
for (int p = 0; p < 100; p++) {
System.out.print(audioFile[p] + " ");
} System.out.println();
*/
System.out.print("Enter a name for the output audio file with the text encoded in it : ");
String outAudio = scan.next();
if (!outAudio.endsWith(".wav")) // Check if the filename ends with .wav and add the extension if it doesn't
outAudio += ".wav";
StdAudio.save(outAudio, audioFile);
scan.close();
}
if (command == 2) {
System.out.print("Enter audio file name that you want to decode (must be a wav file) : ");
String audioToDecode = scan.next();
//System.out.println();
if (!audioToDecode.endsWith(".wav")) // Check if the filename ends with .wav and add the extension if it doesn't
audioToDecode += ".wav";
System.out.print("Enter audio file that is the decoder key (must be a wav file) : ");
String audioKey = scan.next();
//System.out.println();
if (!audioKey.endsWith(".wav")) // Check if the filename ends with .wav and add the extension if it doesn't
audioKey += ".wav";
double[] audioEncoded = StdAudio.read(audioToDecode);
double[] key = StdAudio.read(audioKey);
char [] contents = new char[maxChar];
System.out.println("\nAudio File with data encoded");
for (int z = 0; z < 100; z++) {
System.out.print(audioEncoded[z] + " " );
} System.out.println();
System.out.println("\nOriginal Audio File");
for (int z = 0; z < 100; z++) {
System.out.print(key[z] + " " );
}System.out.println();
System.out.println("\n(Encoded - Key) * 10000");
for (int z = 0; z < 100; z++) {
System.out.print(10000 * ( audioEncoded[z] - key[z] ) + " " );
} System.out.println();
*/
int contentCounter = 0; // Increments whenever a character is added to the contents array
for (int i = 0; i < key.length; i++) {
if (!((audioEncoded[i] - key[i] == 0))) { // If there's a value there, then put it in the char array. If not then nothing was encoded and it can be skipped.
contents[contentCounter] = (char) (Math.round((float) (10000 * ( audioEncoded[i] - key[i] )))); // For some reason the values end up being a tiny bit off and need to be rounded to the nearest int before being converted to characters
contentCounter++;
// DEBUGGING System.out.print(contents[contentCounter-1] + " " + (Math.round((float) (10000 * ( audioEncoded[i] - key[i] )))) + " " + ((10000 * ( audioEncoded[i] - key[i] ))) + "\n" ); //debug line for trying to figure out why the values were off
}
}
System.out.print("Enter the name for a text file to write the data to : ");
String outputName = scan.next();
if (!outputName.endsWith(".txt"))
outputName += ".txt";
// Lots of error catching here, but in short it writes the character array "contents" to the file "outputName"
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(outputName));
} catch (IOException e1) {
e1.printStackTrace();
}
try {
for (int i = 0; i < contentCounter+1; i++) {
writer.write(contents[i]);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
StdAudio.close();
System.out.println("The End.");
}
// Makes a 5 second audio clip of static. 44100 values per second.
public static double[] makeAudio () {
double[] audio = new double[5*44100];
int i;
for (i=0; i < audio.length; i++)
audio[i] = 2*Math.random() - 1; // Generates a random double between -1 and 0.999999
return audio;
}
// Returns the audio file given the name or uses another method to generate a clip of static if the argument is 1
public static double[] getAudioFile(String input) {
double[] audioFile;
if (input.equals("1")) {
audioFile = makeAudio(); // Generates a clip of static.
System.out.print("Please enter a name for the generated audio clip : ");
Scanner scan = new Scanner(System.in);
String name = scan.next();
if (!name.endsWith(".wav")) // Check if the filename ends with .wav and add the extension if it doesn't
name += ".wav";
StdAudio.save(name, audioFile);
}
else {
if (!input.endsWith(".wav")) // Check if the filename ends with .wav and add the extension if it doesn't
input += ".wav";
audioFile = StdAudio.read(input); // Reads in the audio as an array of doubles
}
return audioFile;
}