Java 使用图像LSB隐写术隐藏文件

Java 使用图像LSB隐写术隐藏文件,java,steganography,Java,Steganography,我使用这个隐写术类将文件字节隐藏到LSB或图像的上层。 原始类位于C#中,但我将其转换为java以满足项目需要 但在运行转换后,当使用bytetobool()和booltobyte()方法将字节转换为boolean[]时,会出现超出范围的错误。因为R,G,B值必须是(0-255)。 我如何解决这个错误 import java.awt.image.BufferedImage; import java.awt.Image; import java.awt.Color; imp

我使用这个隐写术类将文件字节隐藏到LSB或图像的上层。 原始类位于C#中,但我将其转换为java以满足项目需要 但在运行转换后,当使用bytetobool()booltobyte()方法将字节转换为boolean[]时,会出现超出范围的错误。因为R,G,B值必须是(0-255)。 我如何解决这个错误

   import java.awt.image.BufferedImage;
   import java.awt.Image;
   import java.awt.Color;
   import java.io.FileInputStream;
   import java.io.FileOutputStream;
   import javax.imageio.IIOImage;
   import java.io.File;
   import java.nio.file.Path;
   import java.nio.file.Files;
   import java.nio.file.Paths;
   import java.io.IOException;
   import java.util.ArrayDeque;
   import java.util.Deque;

   import javax.imageio.ImageIO;

   public class Steganography
   {
   public int height, width, fileNameSize;
   public long FSize;
   String FilePath,ImagePath,fNameWext;
   BufferedImage newimage=null,CoverImage=null;
   byte[] bytestobehidden;
   FileInputStream EncryptedStream=null;
   public Steganography (String imagepath)
   {
      try
      {
       ImagePath=imagepath;
       File imagefile=new File(ImagePath);
       newimage=ImageIO.read(imagefile);
       CoverImage=newimage;
       //CoverImage=new BufferedImage(newimage.getWidth(),newimage.getHeight(),BufferedImage.TYPE_INT_RGB);

      }
      catch(IOException e)
      {e.printStackTrace();}

   }
   public static boolean[] byteToBoolArr(byte x) {
        boolean[] boolArr = new boolean[8];
        boolArr[0] = ((x & 0x01) != 0);
        boolArr[1] = ((x & 0x02) != 0);
        boolArr[2] = ((x & 0x04) != 0);
        boolArr[3] = ((x & 0x08) != 0);

        boolArr[4] = ((x & 0x10) != 0);
        boolArr[5] = ((x & 0x20) != 0);
        boolArr[6] = ((x & 0x40) != 0);
        boolArr[7] = ((x & 0x80) != 0);
        return boolArr;
    }
   public final void byte2bool(byte inp, tangible.RefObject<boolean[]> outp)
    {
        if (inp >= 0 && inp <= 255)
            {
                    for (short i = 7; i >= 0; i--)
                    {
                            if (inp % 2 == 1)
                            {
                                    outp.argValue[i] = true;
                            }
                            else
                            {
                                    outp.argValue[i] = false;
                            }
                            inp /= 2;
                    }
            }
            else
            {
                    throw new RuntimeException("Input number is illegal.");
            }

    }



    public  byte bool2byte(boolean[] inp)
    {

        byte outp = 0;
        for (short i = 7; i >= 0; i--)
        {
            if (inp[i])
            {

                outp += (byte)Math.pow(2.0, (double)(7 - i));
            }
        }
        return outp;
    }

    public void StegoLayer(long FileSize, String filepath, String saveimage, byte[] encryptedbytes) throws IOException
    {
       height = CoverImage.getHeight();
   width = CoverImage.getWidth();
       //BMPMetadata bmpimage=new BMPMetadata(CoverImage);
       File bmpfile = new File(saveimage);
    ImageIO.write(CoverImage,"BMP",bmpfile);
            BufferedImage bmpimage=new BufferedImage(CoverImage.getWidth(),CoverImage.getHeight(),BufferedImage.TYPE_INT_ARGB);
            bmpimage=ImageIO.read(bmpfile);
       //Bitmap loadedTrueBitmap = new Bitmap(loadedImage);
       bytestobehidden = encryptedbytes;
               //EncryptedStream=encryptedbytes;
       FSize = FileSize;

       FilePath = filepath;
               File f=new File(FilePath);
              //String fileName=f.getName();
              fNameWext = f.getName();
        int pos = fNameWext.lastIndexOf(".");
        if (pos > 0 && pos < (fNameWext.length() - 1)) { // If '.' is not the first or last character.
           fNameWext = fNameWext.substring(0, pos);
        }
            fileNameSize=fNameWext.length();

        //fileNameSize = Path.GetFileNameWithoutExtension(filepath).length();
            BufferedImage stegoBitmap = StegoLayer(8, bmpimage, 0, (height * (width / 3) * 3) / 3 - fileNameSize - 1, true);
            FSize -= (height * (width / 3) * 3) / 3 - fileNameSize - 1;
            if (FSize > 0)
            {
                    for (int i = 7; i >= 0 && FSize > 0; i--)
                    {
                            stegoBitmap = StegoLayer(i, stegoBitmap, (((8 - i) * height * (width / 3) * 3) / 3 - fileNameSize - (8 - i)), (((9 - i) * height * (width / 3) * 3) / 3 - fileNameSize - (9 - i)), false);
                            FSize -= (height * (width / 3) * 3) / 3 - 1;
                    }
            }

            ImageIO.write(stegoBitmap, "BMP", bmpfile);

    }


    public BufferedImage StegoLayer(int layer, BufferedImage inputBitmap, long startPosition, long endPosition, boolean writeFileName)
    {
        BufferedImage outputBitmap = inputBitmap;
        layer--;
        int i = 0, j = 0;
        long fileSize = FSize;
        long FNSize = 0;
        boolean[] t = new boolean[8];
        boolean[] rb = new boolean[8];
        boolean[] gb = new boolean[8];
        boolean[] bb = new boolean[8];
        Color pixel = null;
        byte r, g, b;

        if (writeFileName)
        {
            FNSize = fileNameSize;
            //String fileName = Path.GetFileNameWithoutExtension(FilePath);

            //write fileName:
            for (i = 0; i < height && i * (height / 3) < fileNameSize; i++)
                for (j = 0; j < (width / 3) * 3 && i * (height / 3) + (j / 3) < fileNameSize; j++)
                {
                    int z=i * (height / 3) + j / 3;
                    tangible.RefObject<boolean[]> tempRef_t = new tangible.RefObject<boolean[]>(t);
                    byte2bool((byte)fNameWext.charAt(z), tempRef_t);

    //                         t=byteToBoolArr((byte)fNameWext.charAt(z));
                    pixel = new Color(inputBitmap.getRGB(j, i));
                    r = (byte)pixel.getRed();
                    g = (byte)pixel.getGreen();
                    b = (byte)pixel.getBlue();
                    tangible.RefObject<boolean[]> tempRef_rb = new tangible.RefObject<boolean[]>(rb);
                    byte2bool(r, tempRef_rb);
                    rb = tempRef_rb.argValue;

   //                        rb=byteToBoolArr(r);

                    tangible.RefObject<boolean[]> tempRef_gb = new tangible.RefObject<boolean[]>(gb);
                    byte2bool(g, tempRef_gb);
                    gb = tempRef_gb.argValue;

  //                        gb=byteToBoolArr(g);

                    tangible.RefObject<boolean[]> tempRef_bb = new tangible.RefObject<boolean[]>(bb);
                    byte2bool(b, tempRef_bb);
                    bb = tempRef_bb.argValue;

   //                        bb=byteToBoolArr(b);

                    if (j % 3 == 0)
                    {
                        rb[7] = t[0];
                        gb[7] = t[1];
                        bb[7] = t[2];
                    }
                    else if (j % 3 == 1)
                    {
                        rb[7] = t[3];
                        gb[7] = t[4];
                        bb[7] = t[5];
                    }
                    else
                    {
                        rb[7] = t[6];
                        gb[7] = t[7];
                    }

                    Color result = new Color((int)bool2byte(rb), (int)bool2byte(gb), (int)bool2byte(bb));
                    outputBitmap.setRGB(j, i, result.getRGB());
                }
            i--;
        }
        //write file (after file name):
        int tempj = j;

        for (; i < height && i * (height / 3) < endPosition - startPosition + FNSize && startPosition + i * (height / 3) < fileSize + FNSize; i++)
            for (j = 0; j < (width / 3) * 3 && i * (height / 3) + (j / 3) < endPosition - startPosition + FNSize && startPosition + i * (height / 3) + (j / 3) < fileSize + FNSize; j++)
            {
                if (tempj != 0)
                {
                    j = tempj;
                    tempj = 0;
                }
                 tangible.RefObject<boolean[]> tempRef_t = new tangible.RefObject<boolean[]>(t);
                 long k=startPosition + i * (height / 3) + j / 3 - FNSize;
                byte2bool(bytestobehidden[(int)k], tempRef_t);

                 pixel = new Color(inputBitmap.getRGB(j, i));
                    r = (byte)pixel.getRed();
                    g = (byte)pixel.getGreen();
                    b = (byte)pixel.getBlue();
                    tangible.RefObject<boolean[]> tempRef_rb = new tangible.RefObject<boolean[]>(rb);
                    byte2bool(r, tempRef_rb);
                    rb = tempRef_rb.argValue;

       //                         rb=byteToBoolArr(r);

                    tangible.RefObject<boolean[]> tempRef_gb = new tangible.RefObject<boolean[]>(gb);
                    byte2bool(g, tempRef_gb);
                    gb = tempRef_gb.argValue;
       //                        gb=byteToBoolArr(g);

                    tangible.RefObject<boolean[]> tempRef_bb = new tangible.RefObject<boolean[]>(bb);
                    byte2bool(b, tempRef_bb);
                    bb = tempRef_bb.argValue;

   //                         bb=byteToBoolArr(b);

                if (j % 3 == 0)
                {
                    rb[layer] = t[0];
                    gb[layer] = t[1];
                    bb[layer] = t[2];
                }
                else if (j % 3 == 1)
                {
                    rb[layer] = t[3];
                    gb[layer] = t[4];
                    bb[layer] = t[5];
                }
                else
                {
                    rb[layer] = t[6];
                    gb[layer] = t[7];
                }
                Color result =new Color((int)bool2byte(rb), (int)bool2byte(gb), (int)bool2byte(bb));
                outputBitmap.setRGB(j, i, result.getRGB());

            }
        long tempFS = fileSize, tempFNS = fileNameSize;
        r = (byte)(tempFS % 100);
        tempFS /= 100;
        g = (byte)(tempFS % 100);
        tempFS /= 100;
        b = (byte)(tempFS % 100);
        Color flenColor = new Color(r, g, b);
        outputBitmap.setRGB(width - 1, height - 1, flenColor.getRGB());

        r = (byte)(tempFNS % 100);
        tempFNS /= 100;
        g = (byte)(tempFNS % 100);
        tempFNS /= 100;
        b = (byte)(tempFNS % 100);
        Color fnlenColor =new Color(r, g, b);
        outputBitmap.setRGB(width - 2, height - 1, fnlenColor.getRGB());

        return outputBitmap;
    }
    public byte[] ExtractLayer(tangible.RefObject<String> ExtFName)
    {
        height = CoverImage.getHeight();
    width = CoverImage.getWidth();

       BufferedImage StegoBitmap = CoverImage;
        int i, j = 0;
        boolean[] t = new boolean[8];
        boolean[] rb = new boolean[8];
        boolean[] gb = new boolean[8];
        boolean[] bb = new boolean[8];
        Color pixel =null;
        byte r, g, b;
        pixel = new Color(StegoBitmap.getRGB(width - 1, height - 1));
        long fSize = pixel.getRed() + pixel.getGreen() * 100 + pixel.getBlue() * 10000;
        pixel = new Color(StegoBitmap.getRGB(width - 2, height - 1));
        long fNameSize = pixel.getRed() + pixel.getGreen() * 100 + pixel.getBlue() * 10000;
        byte[] ExtBytes = new byte[(int)fSize];
        //tangible.RefObject<String> tempRef_t = new tangible.RefObject<String>(ExtFName);

    ExtFName.argValue = "";
        byte temp;

        //Read file name:
        for (i = 0; i < height && i * (height / 3) < fNameSize; i++)
            for (j = 0; j < (width / 3) * 3 && i * (height / 3) + (j / 3) < fNameSize; j++)
            {
                pixel = new Color(StegoBitmap.getRGB(j, i));
                r = (byte)pixel.getRed();
                g = (byte)pixel.getGreen();
                b = (byte)pixel.getBlue();;
                tangible.RefObject<boolean[]> tempRef_rb = new tangible.RefObject<boolean[]>(rb);
                byte2bool(r, tempRef_rb);
                rb = tempRef_rb.argValue;
                tangible.RefObject<boolean[]> tempRef_gb = new tangible.RefObject<boolean[]>(gb);
                byte2bool(g, tempRef_gb);
                gb = tempRef_gb.argValue;
                tangible.RefObject<boolean[]> tempRef_bb = new tangible.RefObject<boolean[]>(bb);
                byte2bool(b, tempRef_bb);
                bb = tempRef_bb.argValue;


                if (j % 3 == 0)
                {
                    t[0] = rb[7];
                    t[1] = gb[7];
                    t[2] = bb[7];
                }
                else if (j % 3 == 1)
                {
                    t[3] = rb[7];
                    t[4] = gb[7];
                    t[5] = bb[7];
                }
                else
                {
                    t[6] = rb[7];
                    t[7] = gb[7];
                    temp = bool2byte(t);
                    ExtFName.argValue += (char)temp;
                }
            }

        //Read file on layer 8 (after file name):
        int tempj = j;
        i--;

        for (; i < height && i * (height / 3) < fSize + fNameSize; i++)
            for (j = 0; j < (width / 3) * 3 && i * (height / 3) + (j / 3) < (height * (width / 3) * 3) / 3 - 1 && i * (height / 3) + (j / 3) < fSize + fNameSize; j++)
            {
                if (tempj != 0)
                {
                    j = tempj;
                    tempj = 0;
                }
                pixel = new Color(StegoBitmap.getRGB(j, i));
                r = (byte)pixel.getRed();
                g = (byte)pixel.getGreen();
                b = (byte)pixel.getBlue();;
                tangible.RefObject<boolean[]> tempRef_rb = new tangible.RefObject<boolean[]>(rb);
                byte2bool(r, tempRef_rb);
                rb = tempRef_rb.argValue;
                tangible.RefObject<boolean[]> tempRef_gb = new tangible.RefObject<boolean[]>(gb);
                byte2bool(g, tempRef_gb);
                gb = tempRef_gb.argValue;
                tangible.RefObject<boolean[]> tempRef_bb = new tangible.RefObject<boolean[]>(bb);
                byte2bool(b, tempRef_bb);
                bb = tempRef_bb.argValue;

                if (j % 3 == 0)
                {
                    t[0] = rb[7];
                    t[1] = gb[7];
                    t[2] = bb[7];
                }
                else if (j % 3 == 1)
                {
                    t[3] = rb[7];
                    t[4] = gb[7];
                    t[5] = bb[7];
                }
                else
                {
                    t[6] = rb[7];
                    t[7] = gb[7];
                    temp = bool2byte(t);
                    ExtBytes[(int)(i * (height / 3) + j / 3 - fNameSize)] = temp;
                }
            }

        //Read file on other layers:
        long readedOnL8 = (height * (width / 3) * 3) / 3 - fNameSize - 1;

        for (int layer = 6; layer >= 0 && readedOnL8 + (6 - layer) * ((height * (width / 3) * 3) / 3 - 1) < fSize; layer--)
            for (i = 0; i < height && i * (height / 3) + readedOnL8 + (6 - layer) * ((height * (width / 3) * 3) / 3 - 1) < fSize; i++)
                for (j = 0; j < (width / 3) * 3 && i * (height / 3) + (j / 3) + readedOnL8 + (6 - layer) * ((height * (width / 3) * 3) / 3 - 1) < fSize; j++)
                {
                 pixel = new Color(StegoBitmap.getRGB(j, i));
                r = (byte)pixel.getRed();
                g = (byte)pixel.getGreen();
                b = (byte)pixel.getBlue();;
                tangible.RefObject<boolean[]> tempRef_rb = new tangible.RefObject<boolean[]>(rb);
                byte2bool(r, tempRef_rb);
                rb = tempRef_rb.argValue;
                tangible.RefObject<boolean[]> tempRef_gb = new tangible.RefObject<boolean[]>(gb);
                byte2bool(g, tempRef_gb);
                gb = tempRef_gb.argValue;
                tangible.RefObject<boolean[]> tempRef_bb = new tangible.RefObject<boolean[]>(bb);
                byte2bool(b, tempRef_bb);
                bb = tempRef_bb.argValue;

                    if (j % 3 == 0)
                    {
                        t[0] = rb[layer];
                        t[1] = gb[layer];
                        t[2] = bb[layer];
                    }
                    else if (j % 3 == 1)
                    {
                        t[3] = rb[layer];
                        t[4] = gb[layer];
                        t[5] = bb[layer];
                    }
                    else
                    {
                        t[6] = rb[layer];
                        t[7] = gb[layer];
                        temp = bool2byte(t);
                        long k=i * (height / 3) + j / 3 + (6 - layer) * ((height * (width / 3) * 3) / 3 - 1) + readedOnL8;
                        ExtBytes[(int)k] = temp;
                    }
                }
        return ExtBytes;

    }
}
导入java.awt.image.buffereImage;
导入java.awt.Image;
导入java.awt.Color;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入javax.imageio.IIOImage;
导入java.io.File;
导入java.nio.file.Path;
导入java.nio.file.Files;
导入java.nio.file.path;
导入java.io.IOException;
导入java.util.ArrayDeque;
导入java.util.Deque;
导入javax.imageio.imageio;
公开类隐写术
{
公共int高度、宽度、文件名;
公共长期融资;
字符串FilePath、ImagePath、fNameWext;
BuffereImage newimage=null,CoverImage=null;
字节[]bytestobehidden;
FileInputStream EncryptedStream=null;
公共隐写术(字符串图像路径)
{
尝试
{
ImagePath=ImagePath;
文件imagefile=新文件(ImagePath);
newimage=ImageIO.read(imagefile);
CoverImage=newimage;
//CoverImage=new BufferedImage(newimage.getWidth(),newimage.getHeight(),BufferedImage.TYPE\u INT\u RGB);
}
捕获(IOE异常)
{e.printStackTrace();}
}
公共静态布尔[]byteToBoolar(字节x){
boolean[]boolArr=新的boolean[8];
boolArr[0]=((x&0x01)!=0);
boolArr[1]=((x&0x02)!=0);
boolArr[2]=((x&0x04)!=0);
boolArr[3]=((x&0x08)!=0);
boolArr[4]=((x&0x10)!=0);
boolArr[5]=((x&0x20)!=0);
boolArr[6]=((x&0x40)!=0);
boolArr[7]=((x&0x80)!=0);
返回布尔拉尔;
}
公共最终无效字节2池(字节inp,有形.reObject输出)
{
如果(inp>=0&&inp=0;i--)
{
如果(输入%2==1)
{
输出argValue[i]=真;
}
其他的
{
输出argValue[i]=false;
}
inp/=2;
}
}
其他的
{
抛出新的RuntimeException(“输入编号非法”);
}
}
公共字节bool2byte(boolean[]inp)
{
字节输出=0;
对于(短i=7;i>=0;i--)
{
if(inp[i])
{
输出+=(字节)数学功率(2.0,(双精度)(7-i));
}
}
返回输出;
}
public void StegoLayer(长文件大小、字符串文件路径、字符串saveimage、字节[]encryptedbytes)引发IOException
{
高度=CoverImage.getHeight();
宽度=CoverImage.getWidth();
//BMPMetadata bmpimage=新的BMPMetadata(封面图像);
File bmpfile=新文件(saveimage);
ImageIO.write(封面图像,“BMP”,BMP文件);
BuffereImage bmpimage=新的BuffereImage(CoverImage.getWidth()、CoverImage.getHeight()、BuffereImage.TYPE\u INT\u ARGB);
bmp图像=图像读取(bmp文件);
//位图loadedTrueBitmap=新位图(loadedImage);
bytestobehidden=encryptedbytes;
//EncryptedStream=encryptedbytes;
FSize=文件大小;
FilePath=FilePath;
文件f=新文件(文件路径);
//字符串文件名=f.getName();
fNameWext=f.getName();
int pos=fNameWext.lastIndexOf(“.”);
if(pos>0&&pos<(fNameWext.length()-1)){//if.'不是第一个或最后一个字符。
fNameWext=fNameWext.子字符串(0,位置);
}
fileNameSize=fNameWext.length();
//fileNameSize=Path.GetFileNameWithoutExtension(filepath.length();
BuffereImage-stegoBitmap=StegoLayer(8,bmp图像,0,(高度*(宽度/3)*3)/3-fileNameSize-1,true);
FSize-=(高度*(宽度/3)*3)/3-fileNameSize-1;
如果(FSize>0)
{
对于(int i=7;i>=0&&FSize>0;i--)
{
stegoBitmap=StegoLayer(i,stegoBitmap,((8-i)*高度*(宽度/3)*3)/3-文件名称化-(8-i)),((9-i)*高度*(宽度/3)*3)/3-文件名称化-(9-i)),false);
FSize-=(高度*(宽度/3)*3)/3-1;
}
}
写入(stegoBitmap,“BMP”,bmpfile);
}
公共BuffereImage StegoLayer(int层、BuffereImage inputBitmap、长起始位置、长结束位置、布尔writeFileName)
{
BuffereImage outputBitmap=输入位图;
层--;
int i=0,j=0;
长文件大小=FSize;
长FNSize=0;
布尔值[]t=新的布尔值[8];
布尔值[]rb=新的布尔值[8];
布尔值[]gb=新布尔值[8];
布尔值[]bb=新布尔值[8];
颜色像素=空;
字节r,g,b;
if(writeFileName)
{
FNSize=filenamize;
//String fileName=Path.GetFileNameWithoutExtension(FilePath);
//写入文件名:
对于(i=0;ipublic final void byte2bool(byte inp, tangible.RefObject<boolean[]> outp) {
    if (inp >= 0 && inp <= 255)