使用图像LSB Steganography隐藏文件

时间:2018-02-21 12:04:48

标签: java steganography

使用此Steganography类将文件字节隐藏到LSB或图像的上层。 原始课程在 C#但我将其转换为 java 以满足项目需求 但是当我运行转换后,当将字节转换为布尔[] 时,我有超出范围错误,反之亦然,使用 bytetobool() booltobyte() methods。因为 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;

    }
}

this the whole stack error

1 个答案:

答案 0 :(得分:0)

您的错误出现在方法byte2bool()中(如堆栈跟踪所示):

public final void byte2bool(byte inp, tangible.RefObject<boolean[]> outp) {
    if (inp >= 0 && inp <= 255)
Java中的

byte始终是签名的,因此在-128127的范围内。与255的比较会导致这样的错误。