Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Strong在更改一位时更改WAV文件。隐写术_Java_Wav_Steganography - Fatal编程技术网

Java Strong在更改一位时更改WAV文件。隐写术

Java Strong在更改一位时更改WAV文件。隐写术,java,wav,steganography,Java,Wav,Steganography,encode_text()函数实现了LSB编码方法。首先记录消息长度,然后记录消息本身 numberOfBits分配用于写入消息的位数。写入一个字节的一位或两位或三位 这种编码方法使用一个位作为记录,声音的变化不应该被耳朵注意到。以及对眼睛图像的改变。但事实并非如此。由于某些原因,声音的开头会更改为“噪波”。这不应该 read()和save()确定,如果读取数据文件并将其刻录,则不会发生任何更改 问题是encode_text()函数有什么问题。或者我做错了什么 import java.io.*;

encode_text()函数实现了LSB编码方法。首先记录消息长度,然后记录消息本身

numberOfBits分配用于写入消息的位数。写入一个字节的一位或两位或三位

这种编码方法使用一个位作为记录,声音的变化不应该被耳朵注意到。以及对眼睛图像的改变。但事实并非如此。由于某些原因,声音的开头会更改为“噪波”。这不应该

read()save()确定,如果读取数据文件并将其刻录,则不会发生任何更改

问题是encode_text()函数有什么问题。或者我做错了什么

import java.io.*;
import java.util.Arrays;

public class wavIO
{

private String myPath;
private long myChunkSize;
private long mySubChunk1Size;
private int myFormat;
private long myChannels;
private long mySampleRate;
private long myByteRate;
private int myBlockAlign;
private int myBitsPerSample;
private long myDataSize;

public byte[] myData;

public String getPath()
{
    return myPath;
}
public void setPath(String newPath)
{
    myPath = newPath;
}

public wavIO()
    {
    myPath = "";
    }
public wavIO(String tmpPath)
    {
    myPath = tmpPath;
    }

// read a wav file into this class
public boolean read()
{
    DataInputStream inFile = null;
    myData = null;
    byte[] tmpLong = new byte[4];
    byte[] tmpInt = new byte[2];

    try
    {
        inFile = new DataInputStream(new FileInputStream(myPath));

        //System.out.println("Reading wav file...\n"); // for debugging only

        String chunkID = "" + (char)inFile.readByte() + (char)inFile.readByte() + (char)inFile.readByte() + (char)inFile.readByte();

        inFile.read(tmpLong); // read the ChunkSize
        myChunkSize = byteArrayToLong(tmpLong);

        String format = "" + (char)inFile.readByte() + (char)inFile.readByte() + (char)inFile.readByte() + (char)inFile.readByte();

        // print what we've read so far
        //System.out.println("chunkID:" + chunkID + " chunk1Size:" + myChunkSize + " format:" + format); // for debugging only



        String subChunk1ID = "" + (char)inFile.readByte() + (char)inFile.readByte() + (char)inFile.readByte() + (char)inFile.readByte();

        inFile.read(tmpLong); // read the SubChunk1Size
        mySubChunk1Size = byteArrayToLong(tmpLong);

        inFile.read(tmpInt); // read the audio format.  This should be 1 for PCM
        myFormat = byteArrayToInt(tmpInt);

        inFile.read(tmpInt); // read the # of channels (1 or 2)
        myChannels = byteArrayToInt(tmpInt);

        inFile.read(tmpLong); // read the samplerate
        mySampleRate = byteArrayToLong(tmpLong);

        inFile.read(tmpLong); // read the byterate
        myByteRate = byteArrayToLong(tmpLong);

        inFile.read(tmpInt); // read the blockalign
        myBlockAlign = byteArrayToInt(tmpInt);

        inFile.read(tmpInt); // read the bitspersample
        myBitsPerSample = byteArrayToInt(tmpInt);
        // print what we've read so far
        //System.out.println("SubChunk1ID:" + subChunk1ID + " SubChunk1Size:" + mySubChunk1Size + " AudioFormat:" + myFormat + " Channels:" + myChannels + " SampleRate:" + mySampleRate);


        // read the data chunk header - reading this IS necessary, because not all wav files will have the data chunk here - for now, we're just assuming that the data chunk is here
        String dataChunkID = "" + (char)inFile.readByte() + (char)inFile.readByte() + (char)inFile.readByte() + (char)inFile.readByte();

        inFile.read(tmpLong); // read the size of the data
        myDataSize = byteArrayToLong(tmpLong);


        // read the data chunk
        myData = new byte[(int)myDataSize];
        inFile.read(myData);

        // close the input stream
        inFile.close();

    }
    catch(Exception e)
    {
        return false;
    }

    return true; // this should probably be something more descriptive
}

// write out the wav file
public boolean save(String outputPath)
{
    try
    {
        //DataOutputStream outFile  = new DataOutputStream(new FileOutputStream(myPath));
        DataOutputStream outFile  = new DataOutputStream(new FileOutputStream(outputPath));

        // write the wav file per the wav file format
        outFile.writeBytes("RIFF");                 // 00 - RIFF
        outFile.write(intToByteArray((int)myChunkSize), 0, 4);      // 04 - how big is the rest of this file?
        outFile.writeBytes("WAVE");                 // 08 - WAVE
        outFile.writeBytes("fmt ");                 // 12 - fmt 
        outFile.write(intToByteArray((int)mySubChunk1Size), 0, 4);  // 16 - size of this chunk
        outFile.write(shortToByteArray((short)myFormat), 0, 2);     // 20 - what is the audio format? 1 for PCM = Pulse Code Modulation
        outFile.write(shortToByteArray((short)myChannels), 0, 2);   // 22 - mono or stereo? 1 or 2?  (or 5 or ???)
        outFile.write(intToByteArray((int)mySampleRate), 0, 4);     // 24 - samples per second (numbers per second)
        outFile.write(intToByteArray((int)myByteRate), 0, 4);       // 28 - bytes per second
        outFile.write(shortToByteArray((short)myBlockAlign), 0, 2); // 32 - # of bytes in one sample, for all channels
        outFile.write(shortToByteArray((short)myBitsPerSample), 0, 2);  // 34 - how many bits in a sample(number)?  usually 16 or 24
        outFile.writeBytes("data");                 // 36 - data
        outFile.write(intToByteArray((int)myDataSize), 0, 4);       // 40 - how big is this data chunk
        outFile.write(myData);                      // 44 - the actual data itself - just a long string of numbers
    }
    catch(Exception e)
    {
        System.out.println(e.getMessage());
        return false;
    }

    return true;
}

// return a printable summary of the wav file
public String getSummary()
{
    //String newline = System.getProperty("line.separator");
    String newline = "<br>";
    String summary = "<html>Format: " + myFormat + newline + "Channels: " + myChannels + newline + "SampleRate: " + mySampleRate + newline + "ByteRate: " + myByteRate + newline + "BlockAlign: " + myBlockAlign + newline + "BitsPerSample: " + myBitsPerSample + newline + "DataSize: " + myDataSize + "</html>";
    return summary;
}


// ===========================
// CONVERT BYTES TO JAVA TYPES
// ===========================

// these two routines convert a byte array to a unsigned short
public static int byteArrayToInt(byte[] b)
{
    int start = 0;
    int low = b[start] & 0xff;
    int high = b[start+1] & 0xff;
    return (int)( high << 8 | low );
}


// these two routines convert a byte array to an unsigned integer
public static long byteArrayToLong(byte[] b)
{
    int start = 0;
    int i = 0;
    int len = 4;
    int cnt = 0;
    byte[] tmp = new byte[len];
    for (i = start; i < (start + len); i++)
    {
        tmp[cnt] = b[i];
        cnt++;
    }
    long accum = 0;
    i = 0;
    for ( int shiftBy = 0; shiftBy < 32; shiftBy += 8 )
    {
        accum |= ( (long)( tmp[i] & 0xff ) ) << shiftBy;
        i++;
    }
    return accum;
}


// ===========================
// CONVERT JAVA TYPES TO BYTES
// ===========================
// returns a byte array of length 4
private static byte[] intToByteArray(int i)
{
    byte[] b = new byte[4];
    b[0] = (byte) (i & 0x00FF);
    b[1] = (byte) ((i >> 8) & 0x000000FF);
    b[2] = (byte) ((i >> 16) & 0x000000FF);
    b[3] = (byte) ((i >> 24) & 0x000000FF);
    return b;
}

// convert a short to a byte array
public static byte[] shortToByteArray(short data)
{
    return new byte[]{(byte)(data & 0xff),(byte)((data >>> 8) & 0xff)};
}


public void encode(String text, int numberOfBits)
{
    byte[] byteMessage = text.getBytes();
    byte[] messageLength = bit_conversion(byteMessage.length);
    encodeText(messageLength, myData, 0, numberOfBits);
    encodeText(byteMessage, myData, 32, numberOfBits);  
}

private void encodeText(byte[] addition, byte[] byteDataInputWav, int offset, int numberOfBits)
{
    if(addition.length + offset > byteDataInputWav.length)
    {
        System.out.println("File not long enough!");
    }
    else
    {
        for(int i=0; i<addition.length; ++i)
        {
            int add = addition[i];
            for(int bit=7; bit>=0; --bit, ++offset)
            {
                int b = (add >>> bit) & 1;
                byteDataInputWav[offset] = (byte)((byteDataInputWav[offset] & numberOfBits) | b );
            }
        }
    }
}  

private byte[] bit_conversion(int i)
{
    byte byte3 = (byte)((i & 0xFF000000) >>> 24);
    byte byte2 = (byte)((i & 0x00FF0000) >>> 16);
    byte byte1 = (byte)((i & 0x0000FF00) >>> 8 ); 
byte byte0 = (byte)((i & 0x000000FF)       );
return(new byte[]{byte3,byte2,byte1,byte0});
}

public String decode(String inputPath)
{
    byte[] byteDataOutputWav = myData;
    int length = 0;
int offset2 = 32;
for(int i=0; i<32; ++i)
{
    length = (length << 1) | (byteDataOutputWav[i] & 1);
}
byte[] result = new byte[length];
for(int b=0; b<result.length; ++b )
{
        for(int i=0; i<8; ++i, ++offset2)
        {
            result[b] = (byte)((result[b] << 1) | (byteDataOutputWav[offset2] & 1));
        }
}
    return new String(result);
}


}
import java.io.*;
导入java.util.array;
公共类wavIO
{
私有字符串myPath;
私人长码;
私有长mySubChunk1Size;
私有int-myFormat;
私人长频道;
私家长住;
私人长粘虫;
私有int-myBlockAlign;
私有int myBitsPerSample;
私有长myDataSize;
公共字节[]myData;
公共字符串getPath()
{
返回myPath;
}
公共void setPath(字符串newPath)
{
myPath=newPath;
}
公共wavIO()
{
myPath=“”;
}
公共wavIO(字符串tmpPath)
{
myPath=tmpPath;
}
//将wav文件读入此类
公共布尔读取()
{
DataInputStream infle=null;
myData=null;
字节[]tmpLong=新字节[4];
字节[]tmpInt=新字节[2];
尝试
{
infle=newdatainputstream(newfileinputstream(myPath));
//System.out.println(“读取wav文件…\n”);//仅用于调试
字符串chunkID=“+(char)infle.readByte()+(char)infle.readByte()+(char)infle.readByte()+(char)infle.readByte();
infle.read(tmpLong);//读取ChunkSize
myChunkSize=byteArrayToLong(tmpLong);
字符串格式=“+(char)infle.readByte()+(char)infle.readByte()+(char)infle.readByte()+(char)infle.readByte();
//打印我们到目前为止读到的内容
//System.out.println(“chunkID:+chunkID+”chunk1Size:+myChunkSize+”格式:“+格式);//仅用于调试
字符串subChunk1ID=“+(char)infle.readByte()+(char)infle.readByte()+(char)infle.readByte()+(char)infle.readByte();
infle.read(tmpLong);//读取子缓存大小
mySubChunk1Size=byteArrayToLong(tmpLong);
infle.read(tmpInt);//读取音频格式。这对于PCM应该是1
myFormat=ByteArrayPoint(tmpInt);
infle.read(tmpInt);//读取通道(1或2)的#
myChannels=byteArrayToInt(tmpInt);
infle.read(tmpLong);//读取采样器
mySampleRate=byteArrayToLong(tmpLong);
infle.read(tmpLong);//读字节
粘虫=byteArrayToLong(tmpLong);
infle.read(tmpInt);//读取块对齐
myBlockAlign=byteArrayToInt(tmpInt);
infle.read(tmpInt);//读取位示例
myBitsPerSample=ByteArrayPoint(tmpInt);
//打印我们到目前为止读到的内容
//System.out.println(“SubChunk1ID:+SubChunk1ID+”SubChunk1Size:+mySubChunk1Size+”音频格式:“+myFormat+”频道:“+myChannels+”采样器:“+mySampleRate”);
//读取数据块头-读取数据块头是必要的,因为并非所有wav文件都在这里有数据块-现在,我们只是假设数据块在这里
字符串dataChunkID=“+(char)infle.readByte()+(char)infle.readByte()+(char)infle.readByte()+(char)infle.readByte();
infle.read(tmpLong);//读取数据的大小
myDataSize=byteArrayToLong(tmpLong);
//读取数据块
myData=新字节[(int)myDataSize];
填充读取(myData);
//关闭输入流
infle.close();
}
捕获(例外e)
{
返回false;
}
return true;//这应该是更具描述性的内容
}
//写出wav文件
公共布尔保存(字符串输出路径)
{
尝试
{
//DataOutputStream outFile=新的DataOutputStream(新的FileOutputStream(myPath));
DataOutputStream outFile=新DataOutputStream(新文件OutputStream(outputPath));
//按照wav文件格式写入wav文件
outFile.writeBytes(“RIFF”);//00-RIFF
write(intToByteArray((int)myChunkSize),0,4);//04-此文件的其余部分有多大?
outFile.writeBytes(“WAVE”);//08-WAVE
outFile.writeBytes(“fmt”);//12-fmt
write(intToByteArray((int)mySubChunk1Size),0,4);//16-此块的大小
write(shortToByteArray((short)myFormat),0,2);//20-音频格式是什么?1表示PCM=脉冲编码调制
outFile.write(shortToByteArray((短)MyChannel),0,2);//22-单声道或立体声?1或2?(或5或??)
write(intToByteArray((int)mySampleRate),0,4);//24-每秒采样数(每秒数)
write(intToByteArray((int)myByteRate),0,4);//每秒28字节
write(shortToByteArray((short)myBlockAlign),0,2);//32-#字节在一个样本中,用于所有通道
write(shortToByteArray((short)myBitsPerSample),0,2);//34-一个样本(数字)中有多少位?通常是16或24位
outFile.writeBytes(“数据”);//36-data
write(intToByteArray((int)myDataSize),0,4);//40-这个数据块有多大
outFile.write(myData);//44—实际数据本身—只是一长串数字
}
捕获(例外e)
{
System.out.println(e.getMessage());
返回false;
}
返回真值