|
my mail id is chaitu1240@gmail.com
|
|
|
|
|
sir i need java code for image steganography in order to hide text,image in a BMP image
|
|
|
|
|
THis code will run using command line argument
// Steganography.java
/* A steganography class for hiding text inside a PNG image, and for
extracting the text later.
The class has two public static methods:
* boolean hide(String textFnm, String imFnm)
// the modified image is stored in <imFnm>Msg.png
* boolean reveal(String imFnm)
// the extracted message is stored in <imFnm>.txt
This class stores a stego message (stego for short), which has 2
fields:
<size of binary message>
<binary message>
The stego is spread out over the image's bytes by modifying each
byte's
right most bit (the least significant bit, LSB). So 1 byte of stego
data requires
the modification of 8 bytes of the image (i.e. 1 stego data bit is
stored in
1 image byte).
The stego is added once into the LSBs of the image's bytes at its
beginning.
More details on the stego's fields:
The message size is a Java integer (i.e. 4 bytes long),
which requires 4*8 bytes in the image.
Each byte of the message requires 8 bytes
of storage in the image.
*/
import java.io.*;
import java.awt.*;
import java.util.*;
import java.awt.image.*;
import javax.imageio.*;
public class Steganography
{
private static final int MAX_INT_LEN = 4;
private static final int DATA_SIZE = 8;
// number of image bytes required to store one stego byte
public static boolean hide(String textFnm, String imFnm)
/* hide message read from textFnm inside image read from imFnm;
the resulting image is stored in <inFnm>Msg.png */
{
// read in the message
String inputText = readTextFile(textFnm);
if ((inputText == null) || (inputText.length() == 0))
return false;
byte[] stego = buildStego(inputText);
// access the image's data as a byte array
BufferedImage im = loadImage(imFnm);
if (im == null)
return false;
byte imBytes[] = accessBytes(im);
if (!singleHide(imBytes, stego)) // im is modified with the stego
return false;
// store the modified image in <fnm>Msg.png
String fnm = getFileName(imFnm);
return writeImageToFile( fnm + "Msg.png", im);
} // end of hide()
private static String readTextFile(String fnm)
// read in fnm, returning it as a single string
{
BufferedReader br = null;
StringBuffer sb = new StringBuffer();
try {
br = new BufferedReader(new FileReader( new File(fnm) ));
String text = null;
while ((text = br.readLine()) != null)
sb.append(text + "\n");
}
catch (Exception e) {
System.out.println("Could not completely read " + fnm);
return null;
}
finally {
try {
if (br != null)
br.close();
}
catch (IOException e) {
System.out.println("Problem closing " + fnm);
return null;
}
}
System.out.println("Read in " + fnm);
return sb.toString();
} // end of readTextFile()
private static byte[] buildStego(String inputText)
/* Build a stego (a byte array), made up of 2 fields:
<size of binary message>
<binary message> */
{
// convert data to byte arrays
byte[] msgBytes = inputText.getBytes();
byte[] lenBs = intToBytes(msgBytes.length);
int totalLen = lenBs.length + msgBytes.length;
byte[] stego = new byte[totalLen]; // for holding the resulting
stego
// combine the 2 fields into one byte array
// public static void arraycopy(Object src, int srcPos, Object
dest, int destPos, int length);
System.arraycopy(lenBs, 0, stego, 0, lenBs.length); //
length of binary message
System.arraycopy(msgBytes, 0, stego, lenBs.length,
msgBytes.length); // binary message
// System.out.println("Num. pixels to store fragment " + i + ": " +
totalLen*DATA_SIZE);
return stego;
} // end of buildStego()
private static byte[] intToBytes(int i)
// split integer i into a MAX_INT_LEN-element byte array
{
// map the parts of the integer to a byte array
byte[] integerBs = new byte[MAX_INT_LEN];
integerBs[0] = (byte) ((i >>> 24) & 0xFF);
integerBs[1] = (byte) ((i >>> 16) & 0xFF);
integerBs[2] = (byte) ((i >>> 8) & 0xFF);
integerBs[3] = (byte) (i & 0xFF);
// for (int j=0; j < integerBs.length; j++)
// System.out.println(" integerBs[ " + j + "]: " + integerBs[j]);
return integerBs;
} // end of intToBytes()
private static BufferedImage loadImage(String imFnm)
// read the image from the imFnm file
{
BufferedImage im = null;
try {
im = ImageIO.read( new File(imFnm) );
System.out.println("Read " + imFnm);
}
catch (IOException e)
{ System.out.println("Could not read image from " + imFnm); }
return im;
} // end of loadImage()
private static byte[] accessBytes(BufferedImage image)
// access the data bytes in the image
{
WritableRaster raster = image.getRaster();
DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer();
return buffer.getData();
} // end of accessBytes()
private static boolean singleHide(byte[] imBytes, byte[] stego)
// store stego in image bytes
{
int imLen = imBytes.length;
System.out.println("Byte length of image: " + imLen);
int totalLen = stego.length;
System.out.println("Total byte length of message: " + totalLen);
// check that the stego will fit into the image
// multiply stego length by number of image bytes required to store
one stego byte
if ((totalLen*DATA_SIZE) > imLen) {
System.out.println("Image not big enough for message");
return false;
}
hideStego(imBytes, stego, 0); // hide at start of image
return true;
} // end of singleHide()
private static void hideStego(byte[] imBytes, byte[] stego, int
offset)
// store stego in image starting at byte posn offset
{
for (int i = 0; i < stego.length; i++) { // loop through
stego
int byteVal = stego[i];
for(int j=7; j >= 0; j--) { // loop through the 8 bits of each
stego byte
int bitVal = (byteVal >>> j) & 1;
// change last bit of image byte to be the stego bit
imBytes[offset] = (byte)((imBytes[offset] & 0xFE) | bitVal);
offset++;
}
}
} // end of hideStego()
private static String getFileName(String fnm)
// extract the name from the filename without its suffix
{
int extPosn = fnm.lastIndexOf('.');
if (extPosn == -1) {
System.out.println("No extension found for " + fnm);
return fnm; // use the original file name
}
return fnm.substring(0, extPosn);
} // end of getFileName()
private static boolean writeImageToFile(String outFnm, BufferedImage
im)
// save the im image in a PNG file called outFnm
{
if (!canOverWrite(outFnm))
return false;
try {
ImageIO.write(im, "png", new File(outFnm));
System.out.println("Image written to PNG file: " + outFnm);
return true;
}
catch(IOException e)
{ System.out.println("Could not write image to " + outFnm);
return false;
}
} // end of writeImageToFile();
private static boolean canOverWrite(String fnm)
/* If fnm already exists, get a response from the
user about whether it should be overwritten or not. */
{
File f = new File(fnm);
if (!f.exists())
return true; // can overewrite since the file is new
// prompt the user about whether the file can be overwritten
Scanner in = new Scanner(System.in);
String response;
System.out.print("File " + fnm + " already exists. ");
while (true) {
System.out.print("Overwrite (y|n)? ");
response = in.nextLine().trim().toLowerCase();
if (response.startsWith("n")) // no
return false;
else if (response.startsWith("y")) // yes
return true;
}
} // end of canOverWrite()
// --------------------------- reveal a message
-----------------------------------
public static boolean reveal(String imFnm)
/* Retrieve the hidden message from imFnm from the beginning
of the image after first extractibg its length information.
The extracted message is stored in <imFnm>.txt
*/
{
// get the image's data as a byte array
BufferedImage im = loadImage(imFnm);
if (im == null)
return false;
byte[] imBytes = accessBytes(im);
System.out.println("Byte length of image: " + imBytes.length);
// get msg length at the start of the image
int msgLen = getMsgLength(imBytes, 0);
if (msgLen == -1)
return false;
System.out.println("Byte length of message: " + msgLen);
// get message located after the length info in the image
String msg = getMessage(imBytes, msgLen, MAX_INT_LEN*DATA_SIZE);
if (msg != null) {
String fnm = getFileName(imFnm);
return writeStringToFile(fnm + ".txt", msg); // save message in
a text file
}
else {
System.out.println("No message found");
return false;
}
} // end of reveal()
private static int getMsgLength(byte[] imBytes, int offset)
// retrieve binary message length from the image
{
byte[] lenBytes = extractHiddenBytes(imBytes, MAX_INT_LEN, offset);
// get the binary message length as a byte array
if (lenBytes == null)
return -1;
// for (int j=0; j < lenBytes.length; j++)
// System.out.println(" lenBytes[ " + j + "]: " + lenBytes[j]);
// convert the byte array into an integer
int msgLen = ((lenBytes[0] & 0xff) << 24) |
((lenBytes[1] & 0xff) << 16) |
((lenBytes[2] & 0xff) << 8) |
(lenBytes[3] & 0xff);
// System.out.println("Message length: " + msgLen);
if ((msgLen <= 0) || (msgLen > imBytes.length)) {
System.out.println("Incorrect message length");
return -1;
}
// else
// System.out.println("Revealed message length: " + msgLen);
return msgLen;
} // end of getMsgLength()
private static String getMessage(byte[] imBytes, int msgLen, int
offset)
/* Extract a binary message of size msgLen from the image, and
convert it to a string
*/
{
byte[] msgBytes = extractHiddenBytes(imBytes, msgLen, offset);
// the message is msgLen bytes long
if (msgBytes == null)
return null;
String msg = new String(msgBytes);
// check the message is all characters
if (isPrintable(msg)) {
// System.out.println("Found message: \"" + msg + "\"");
return msg;
}
else
return null;
} // end of getMessage()
private static byte[] extractHiddenBytes(byte[] imBytes, int size,
int offset)
// extract 'size' hidden data bytes, starting from 'offset' in the
image bytes
{
int finalPosn = offset + (size*DATA_SIZE);
if (finalPosn > imBytes.length) {
System.out.println("End of image reached");
return null;
}
byte[] hiddenBytes = new byte[size];
for (int j = 0; j < size; j++) { // loop through each hidden
byte
for (int i=0; i < DATA_SIZE; i++) { // make one hidden byte
from DATA_SIZE image bytes
hiddenBytes[j] = (byte) ((hiddenBytes[j] << 1) |
(imBytes[offset] & 1));
// shift existing 1 left; store right most
bit of image byte
offset++;
}
}
return hiddenBytes;
} // end of extractHiddenBytes()
private static boolean isPrintable(String str)
// is the string printable?
{
for (int i=0; i < str.length(); i++)
if (!isPrintable(str.charAt(i))) {
System.out.println("Unprintable character found");
return false;
}
return true;
} // end of isPrintable()
private static boolean isPrintable(int ch)
// is ch a 7-bit ASCII character that could (sensibly) be printed?
{
if (Character.isWhitespace(ch) && (ch < 127)) // whitespace, 7-bit
return true;
else if ((ch > 32) && (ch < 127))
return true;
return false;
} // end of isPrintable()
private static boolean writeStringToFile(String outFnm, String
msgStr)
// write the message string into the outFnm text file
{
if (!canOverWrite(outFnm))
return false;
try {
FileWriter out = new FileWriter( new File(outFnm) );
out.write(msgStr);
out.close();
System.out.println("Message written to " + outFnm);
return true;
}
catch(IOException e)
{ System.out.println("Could not write message to " + outFnm);
return false;
}
} // end of writeStringToFile()
//} // end of Steganography class
public static void main(String args[])
{
Steganography st= new Steganography();
st.hide(args[0],args[1]);
}
}
|
|
|
|
|
I am new in it. First I Congrats for your article. I am doing Steganography project for image hiding. Please tell me how do I can get the image pixels in Array. If you don't mind you send any related project to me.
Regards
M.Arulraj
|
|
|
|
|
Try this to copy the pixels into an array:
Bitmap bmp = (Bitmap)Image.FromFile("demo1.bmp");
int width = bmp.Width, height=bmp.Width;
BitmapData data = bmp.LockBits(
new Rectangle(0,0,bmp.Width,bmp.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format24bppRgb);
int length = data.Stride*bmp.Height;
byte[] stream = new byte[length];
Marshal.Copy(data.Scan0, stream, 0, length);
bmp.UnlockBits(oldData);
bmp.Dispose();
This statement is false.
|
|
|
|
|
how ican hide image inside image
|
|
|
|
|
Hi friend I saw your msg. In my idea, you will follow LSB(Last significant bit) method.
In this model, each Original-image pixel bits are overwrite on the embedded-image's last bit of each pixels bytes.
First you will get image pixels using Array. If you follow
Java Applet, which have many methods. Java Swings is also very useful to it.
In Java Vector concept is more efficient than the Array concept, Which is similar to the Array concept.
I am also doing this project. If you have any information please send to me.
.....see you next msg friend
my e-mail id vhnsncembedded@gmail.com
regards by
|
|
|
|
|
please help me for this project
|
|
|
|
|
If soo please provide it to pprasad84@yahoo.com
|
|
|
|
|
Please excuse my bad English ... what is a "base paper"?
This statement is false.
|
|
|
|
|
Hello
Can you help me this topic?
|
|
|
|
|
Hi, I need implementation in java using image png or jpeg ...
I need to help ..
Please
Rafa
|
|
|
|
|
|
Hi, I need implementation in java using image GIF ...
I need to help ..
Please
Rafa
|
|
|
|
|
Are you a brazilian? I am searching for steganography in java code too... I have some files about the hidden messages on images. Send me a e-mail if you are interesting. Bye!
|
|
|
|
|
Respected Sir,
I am also searching for source code for stegnography in core java so please help me about it.my mail id is chaitu1240@gmail.com
|
|
|
|
|
You can find more information on this site
http://www.infosyssec.org/infosyssec/security/stendig1.htm . Any
doubt, contact.
|
|
|
|
|
Congratulations for your article, but I have only VC6++. Can you tell me how do I can convert all projects (Steganography 1-12). I tried to convert using Project Converter VC++7 to VC++6 made by Stephane Rodriguez, but for some reason I didn't get the project to open.
|
|
|
|
|
When I embed data to PNG image. The problem is Input Image PNG with pixel format 24bppRgb when it comple te,the Cover Image have pixel format is 32bppArgb. Please help me to save it with default pixel format. Thank for read my message and sorry about my english. I'm vietnamese.
|
|
|
|
|
In CryptUtility.SaveBitmap(), the image is copied into a new image.
If you want to keep the original color depth, you can comment out the following lines:
<br />
<br />
<br />
<br />
<br />
bitmap.Save(fileName, format);<br />
bitmap.Dispose();<br />
|
|
|
|
|
I have an object Bitmap in a format Format8bppIndexed , but when I used this format, I can't use the SetPixel method of Bitmap because it's not supported by indexed image.
How I set de pixel in this type of Bitmap?
Thank for all response,
Alexsander "Axia" Antunes
|
|
|
|
|
Indexed bitmaps don't support RGB colors, that's why you cannot set pixels. An indexed pixel is an index in the palette, not a color.
You have to convert to image to a non-indexed format. I think it should work like that:
Bitmap new Bmp = new Bitmap( bmp.Width, bmp.Height, PixelFormat.Format24bppRgb );<br />
Graphics g = new Graphics.FromImage(newBmp);<br />
d.drawImage(bmp, 0,0);
|
|
|
|
|
Respected Sir,
I am also searching for source code for stegnography in core java so please help me about it.my mail id is chaitu1240@gmail.com
|
|
|
|
|
FWIW, According to my tests, the following version of GetBit is nearly 12 times faster (on my computer) than the version in this article, and produces the same results.
private static bool GetBit(byte b, byte position)
{
return ((b & (byte)(1 << position)) != 0);
}
Likewise, this version of SetBit is roughly 9.5 times faster (using the new version of GetBit):
private static byte SetBit(byte b, byte position, bool newBitValue)
{
bool bitValue = GetBit(b, position);
if (bitValue != newBitValue)
{
byte positionValue = (byte)(1 << position);
b = (byte)(b ^ positionValue);
}
return b;
}
And this version is roughly 15 times faster:
private static byte SetBit(byte b, byte position, bool newBitValue)
{
byte mask = (byte)(1 << position);
if (newBitValue)
return (byte)(b | mask);
return (byte)(b & ~mask);
}
|
|
|
|
|
I didn't think much about how to set the bits - only wanted to get it done somehow and get on with the interesting part of the app...
Thanks for the hint, next time I'll try to please the performane fanatics, even if the time delay is hardly measureable
And never again I'll try to split an integer by calling .ToString("x") and splitting the string. I found out how to do this without causing chaos. Really.
|
|
|
|
|