Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
h
Designed and Implementation: Renjith G
/************type definition***********************/
/* typedefs */
typedef unsigned char UBYTE;
/***********struture definition********************/
struct steg_header
{
unsigned long datalen;
char key[10];
};
struct BMPFILEHEADER
{
unsigned char bfType; //2 Bitmap identifier. Must be 'BM'.
unsigned int bfSize; //4 Can be set to 0 for for uncompressed bitmaps, which is the kind we have.
short int bfReserved1;//2 Set to 0.
short int bfReserved2;//2 Set to 0.
unsigned int bfOffbits; //4 Specifies the location (in bytes) in the file of the image data.
// For our 8-bit bitmaps, this will be sizeof(BITMAPFILEHEADER) +
//sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * numPaletteEntries.
};
struct BMPINFOHEADER
{
unsigned int biSize; //4 This is the size of the BMPINFOHEADER structure. Thus, it is
//sizeof(BITMAPINFOHEADER).
unsigned int biWidth; //4 The width of the bitmap, in pixels.
unsigned int biHeight; //4 The height of the bitmap, in pixels.
short int biPlanes; //2 Set to 1.
short int biBitCount; //2 The bit depth of the bitmap. For 8-bit bitmaps, this is 8.
unsigned int biCompression; //4 Our bitmaps are uncompressed, so this field is set to 0.
unsigned int biSizeImage; //4 The size of the padded image, in bytes.
unsigned int biXPelsPerMeter; //4 Horizontal resolution, in pixels per meter, of device displaying bitmap. This number is not significant for us, and will be set
to 0.
unsigned int biYPelsPerMeter; //4 Vertical resolution, in pixels per meter, of device displaying bitmap. This number is not significant for us, and will be set to
0.
unsigned int biClrUsed; //4 This indicates how many colors are in the palette.
unsigned int biClrImportant; //4 This indicates how many colors are needed to display the bitmap. We will set it to 0, indicating all colors should be used.
};
/********************************************************/
//Steg.cpp
Designed and Implementation: Renjith G
/*My Special Thanks to -----Peter Kieltyka----For the Main Idea of hiding Data
on LSB of Bitmap File. New program Modified and designed by renjith.
Creation Date ->Saturday, January 31, 2004, 10:48:42 PM
Last Modification ->Tuesday , March 02 , 2004, 10:44:54 PM
*/
#include "steg.h"
#include
#include
#include
//#include
/**************Function Prototypes*************************/
void MediaInfo(char *);
CheckMediaFile (FILE *);
void Eof(void);
void usage(char *);
int MaxCapacity(unsigned long);
int FileSize(FILE *);
int SteganoHide(char *, char *, char *, char *);
int SteganoExtract(char *, char *, char *);
/*************************Usage()*************************/
void usage(char *argv)
{
fprintf(stderr,
"\n\n"
"usage: \t\t To Hide\n"
"%s \n "
"\n\n"
"usage:\t\t To Extract\n"
"%s \n\n"
"\n\n"
"usage:\t\t To get Information about MediaFile File\n"
"%s <-i> "
"\n\n",argv,argv,argv);
exit(-1);
}
/******************EOF()*********************************/
void Eof(void)
{
puts("Error: End of file encountered - So aborting...\n");
}
/********************************************************/
/*********************************************************/
CheckMediaFile (FILE *fpin)
{
int b;
}
/***************FileSize()***********************************/
int FileSize(FILE *fp)
{
unsigned long fsize;
(void)fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
(void)fseek(fp, 0, SEEK_SET);
return(fsize);
}
/**********************************************************/
void MediaInfo(char *fin)
{
fread(&bmih,sizeof(bmih),1,fpin);
printf("Size of %s = %dKB\n",fin,bmih.biSizeImage/1024);
printf("Width of Bitmap File = %d\n", bmih.biWidth );
printf("Height of Bitmap File = %d\n", bmih.biHeight);
hresol = bmih.biXPelsPerMeter/39.3700787401;
vresol = bmih.biYPelsPerMeter/39.3700787401;
printf("Horizontal Resolution = %ld dpi\n",hresol);
printf("Vertical Resolution = %ld dpi\n",vresol);
switch(bmih.biBitCount)
{
case 1:
puts ("Monochrome Image 1bit (2 color)\n");
break;
case 4:
puts ("VGA Image ->4bit (16 color)\n");
break;
case 8:
puts ("SVGA or greyscale ->8bit (256 color)\n");
break;
case 16:
puts ("High Color ->16bit (65536 colour)\n");
break;
case 24:
puts ("True Color ->24bit (16.7 Mio colour)\n");
break;
default:
printf ( "Unknown color depth = %i\n",bmih.biBitCount );
} /*End o 2nd switch*/
if(bmih.biCompression != 0) /*Refer 6th field of BMPinfoHeader structure */
printf("BitMap File <%s> is Compressed\n",fin);
else
printf("Bitmap File <%s> is UnCompressed\n",fin);
}
fclose(fpin);
// printf("file closed");
/***********************SteganoHide()***********************/
/* notes:- when hiding:
a = (a & ~1) | (((b >> (7-k)) & 1) & 1);
this takes the bit of byte 'b' at location 'k' (k goes from 0-7, 0 being the LSB)
and stores it in the LSB of byte 'a'
*/
while(i < n)
{
if(j <= 0)
{
c = 0;
memset(data, 0, sizeof(data)); /* returns data */
j = fread(data+h, 1, sizeof(data)-h, fpdata);
// j = fread(data, 1, sizeof(data), fpdata);
// printf("j==================%d\n",j);
if(h != 0)
{
j += h;
memcpy(data, &steg, sizeof(steg));
h = 0;
}
}
if(j > 0)
{
printf("count=%d\n",count);
printf("the val buf[%d] =%d\n",i,buf[i]);
printf("The data[%d] =%d\n",c,(((data[c] >> (7-k)) & 1) & 1));
// printf("i=%d \t c=%d\n",i,c);
buf[i] = (buf[i] & ~1) | (((data[c] >> (7-k)) & 1) & 1);
printf("the val buf[%d] =%d\n\n\n",i,buf[i]);
count=count+1;
// getch();
k++;
//printf("buff %c\n",buf[i] );
if(k > 7)
{
k = 0;
c++;
j--;
}
}
i++;
} /* End Of While */
fwrite(buf, 1, n, fpout);
x += n;
}
fclose(fpin);
fclose(fpout);
fclose(fpdata);
return(0);
}
/****************Stegano Extraction()********************/
/* note to follow:- when extracting:
a = (a & ~(1 << (7-k))) | ((b & 1) << (7-k));
this assigns 'a' the LSB of 'b' to location 'k' (k goes from 0-7, 0 being the LSB)
*/
int SteganoExtract(char *fin, char *fout, char *key)
{
FILE *fpin, *fpout;
struct steg_header steg = {0};
char buf[BUFSIZE], data[DATASIZE], c;
int done,n,x,i,k,j;
// Get header
x = 0;
j = 0;
k = 0;
done = 0;
puts("Please wait while Extracting............");
memset(data, 0, sizeof(data));
while((n = fread(buf, 1, sizeof(buf), fpin)) && done == 0)
{
if(x == 0)
i = STARTBYTE;
else
i = 0;
while(i < n)
{
if(j < sizeof(steg))
{
data[j] = (data[j] & ~(1 << (7-k))) | ((buf[i] & 1) << (7-k));
k++;
if(k > 7)
{
k = 0;
j++;
}
}
else
{
done = 1;
break;
}
i++;
} /*end of While */
x += n;
}
memcpy(&steg, data, sizeof(steg));
(void)fseek(fpin, 0, SEEK_SET);
// Check key's
if(strcmp(steg.key, key))
{
printf("Incorrect Key! No data for you!\n");
fclose(fpin);
fclose(fpout);
return(-1);
}
// Get data
x = 0;
k = 0;
j = steg.datalen;
i = STARTBYTE+(sizeof(steg)*8);
while(n = fread(buf, 1, sizeof(buf), fpin))
{
if(x != 0)
i = 0;
while(i < n)
{
c = (c & ~(1 << (7-k))) | ((buf[i] & 1) << (7-k));
k++;
if(k > 7)
{
k = 0;
j--;
if(j >= 0)
fputc(c, fpout);
}
i++;
}
x += n;
}
fclose(fpin);
fclose(fpout);
return(0);
}
/********************Main()******************************/
usage(argv[0]);
if(argc == 3)
{
if(strcmp (argv[1],"-i") == 0)
{
//puts("in hai");
MediaInfo(argv[2]);
exit(-1);
}
else
puts("out hai");
usage(argv[0]);
exit(-1);
///////////////////////////srecmp(argv[2],"-i")==0?usage(argv[0]):exit(-1));
}
if(argc == 4)
{
if(strlen(argv[3]) > 10)
{
printf("Sorry, the key cannot be greater then 10 characters long!\n");
exit(-1);
}
*
002 *@author William_Wilson
003 *@version 1.6
004 *Created: May 8, 2007
005 */
006
007 /*
008 *import list
009 */
010 import java.io.File;
011
012 import java.awt.Point;
013 import java.awt.Graphics2D;
014 import java.awt.image.BufferedImage;
015 import java.awt.image.WritableRaster;
016 import java.awt.image.DataBufferByte;
017
018 import javax.imageio.ImageIO;
019 import javax.swing.JOptionPane;
020
021 /*
022 *Class Steganography
023 */
024 public class Steganography
025 {
026
027 /*
028 *Steganography Empty Constructor
029 */
030 public Steganography()
031 {
032 }
033
034 /*
035 *Encrypt an image with text, the output file will be of type .png
036 *@param path The path (folder) containing the image to modify
037 *@param original The name of the image to modify
*@param ext1 The extension type of the image to modify (jpg,
038
png)
039 *@param stegan The output name of the file
040 *@param message The text to hide in the image
*@param type integer representing either basic or advanced
041
encoding
042 */
043 public boolean encode(String path, String original, String ext1, String
stegan, String message)
044 {
045 String file_name = image_path(path,original,ext1);
046 BufferedImage image_orig = getImage(file_name);
047
048 //user space is not necessary for Encrypting
049 BufferedImage image = user_space(image_orig);
050 image = add_text(image,message);
051
05 return(setImage(image,new File(image_path(path,stegan,"png")),"png"
2 ));
053 }
054
055 /*
*Decrypt assumes the image being used is of type .png, extracts the
056
hidden text from an image
*@param path The path (folder) containing the image to extract the
057
message from
058 *@param name The name of the image to extract the message from
059 *@param type integer representing either basic or advanced encoding
060 */
061 public String decode(String path, String name)
062 {
063 byte[] decode;
064 try
065 {
066 //user space is necessary for decrypting
BufferedImage image =
067
user_space(getImage(image_path(path,name,"png")));
068 decode = decode_text(get_byte_data(image));
069 return(new String(decode));
070 }
071 catch(Exception e)
072 {
073 JOptionPane.showMessageDialog(null,
074 "There is no hidden message in this image!","Error",
075 JOptionPane.ERROR_MESSAGE);
076 return "";
077 }
078 }
079
080 /*
081 *Returns the complete path of a file, in the form: path\name.ext
082 *@param path The path (folder) of the file
083 *@param name The name of the file
084 *@param ext The extension of the file
085 *@return A String representing the complete path of a file
086 */
087 private String image_path(String path, String name, String ext)
088 {
089 return path + "/" + name + "." + ext;
090 }
091
092 /*
093 *Get method to return an image file
094 *@param f The complete path name of the image.
095 *@return A BufferedImage of the supplied file path
096 *@see Steganography.image_path
097 */
098 private BufferedImage getImage(String f)
099 {
100 BufferedImage image = null;
101 File file = new File(f);
102
103 try
104 {
105 image = ImageIO.read(file);
106 }
107 catch(Exception ex)
108 {
109 JOptionPane.showMessageDialog(null,
"Image could not be
110
read!","Error",JOptionPane.ERROR_MESSAGE);
111 }
112 return image;
113 }
114
115 /*
116 *Set method to save an image file
117 *@param image The image file to save
118 *@param file File to save the image to
*@param ext The extension and thus format of the file to be
119
saved
120 *@return Returns true if the save is succesful
121 */
122 private boolean setImage(BufferedImage image, File file, String ext)
123 {
124 try
125 {
126 file.delete(); //delete resources used by the File
127 ImageIO.write(image,ext,file);
128 return true;
129 }
130 catch(Exception e)
131 {
132 JOptionPane.showMessageDialog(null,
"File could not be
133
saved!","Error",JOptionPane.ERROR_MESSAGE);
134 return false;
135 }
136 }
137
138 /*
139 *Handles the addition of text into an image
140 *@param image The image to add hidden text to
141 *@param text The text to hide in the image
142 *@return Returns the image with the text embedded in it
143 */
144 private BufferedImage add_text(BufferedImage image, String text)
145 {
146 //convert all items to byte arrays: image, message, message length
147 byte img[] = get_byte_data(image);
148 byte msg[] = text.getBytes();
149 byte len[] = bit_conversion(msg.length);
150 try
151 {
152 encode_text(img, len, 0); //0 first positiong
encode_text(img, msg, 32); //4 bytes of space for length:
153
4bytes*8bit = 32 bits
154 }
155 catch(Exception e)
156 {
157 JOptionPane.showMessageDialog(null,
158 "Target File cannot hold message!", "Error",JOptionPane.ERROR_MESSAGE);
159 }
160 return image;
161 }
162
163 /*
*Creates a user space version of a Buffered Image, for editing and
164
saving bytes
*@param image The image to put into user space, removes compression
165
interferences
166 *@return The user space version of the supplied image
167 */
168 private BufferedImage user_space(BufferedImage image)
169 {
170 //create new_img with the attributes of image
257 for(int i=0; i<32; ++i) //i=24 will also work, as only the 4th
byte contains real data
258 {
259 length = (length << 1) | (image[i] & 1);
260 }
261
262 byte[] result = new byte[length];
263
264 //loop through each byte of text
265 for(int b=0; b<result.length; ++b )
266 {
267 //loop through each bit within a byte of text
268 for(int i=0; i<8; ++i, ++offset)
269 {
//assign bit: [(new byte value) << 1] OR [(text byte) AND
270
1]
result[b] = (byte)((result[b] << 1) | (image[offset]
271
& 1));
272 }
273 }
274 return result;
275 }
276 }