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