Java steganography wrong output

43 views Asked by At

I wanted to learn steganography in java and found a repo on github which seemed simple enough to learn from it: https://github.com/tigerlyb/Steganography-in-Java. I have a problem with the text embedding and extracting - For some reason some characters are incorrectly extracted. I can't figure out the mistake in code since it looks correct and the positions of incorrect characters seems random.

Here is the code from the repository i mentioned before:

// Steganography.java 

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Steganography {
    // embed secret information/TEXT into a "cover image"
        public static BufferedImage embedText(BufferedImage image, String text) {
            int bitMask = 0x00000001;   // define the mask bit used to get the digit
            int bit;                // define a integer number to represent the ASCII number of a character
            int x = 0;              // define the starting pixel x
            int y = 0;              // define the starting pixel y
            for(int i = 0; i < text.length(); i++) {            
                bit = (int) text.charAt(i);     // get the ASCII number of a character
                for(int j = 0; j < 8; j++) {
                    int flag = bit & bitMask;   // get 1 digit from the character
                    if(flag == 1) { 
                        if(x < image.getWidth()) {
                            image.setRGB(x, y, image.getRGB(x, y) | 0x00000001);    // store the bit which is 1 into a pixel's last digit
                            x++;
                        }
                        else {
                            x = 0;
                            y++;
                            image.setRGB(x, y, image.getRGB(x, y) | 0x00000001);    // store the bit which is 1 into a pixel's last digit
                        }
                    } 
                    else {  
                        if(x < image.getWidth()) {
                            image.setRGB(x, y, image.getRGB(x, y) & 0xFFFFFFFE);    // store the bit which is 0 into a pixel's last digit
                            x++;
                        }
                        else {
                            x = 0;
                            y++;
                            image.setRGB(x, y, image.getRGB(x, y) & 0xFFFFFFFE);    // store the bit which is 0 into a pixel's last digit
                        }
                    }
                    bit = bit >> 1;             // get the next digit from the character
                }           
            }
            
            // save the image which contains the secret information to another image file
            try {
                File outputfile = new File("textEmbedded.png"); 
                ImageIO.write(image, "png", outputfile);    
            } catch (IOException e) {
                
            }       
            return image;
        }
        
        // extract secret information/Text from a "cover image"
        public static void extractText(BufferedImage image, int length) {
            System.out.print("Extracting: ");
            int bitMask = 0x00000001;   // define the mask bit used to get the digit
            int x = 0;                  // define the starting pixel x
            int y = 0;                  // define the starting pixel y
            int flag;
            char[] c = new char[length] ;   // define a character array to store the secret information
            for(int i = 0; i < length; i++) {   
                int bit = 0;
                
                // 8 digits form a character
                for(int j = 0; j < 8; j++) {                
                    if(x < image.getWidth()) {
                        flag = image.getRGB(x, y) & bitMask;    // get the last digit of the pixel
                        x++;
                    }
                    else {
                        x = 0;
                        y++;
                        flag = image.getRGB(x, y) & bitMask;    // get the last digit of the pixel
                    }
                    
                    // store the extracted digits into an integer as a ASCII number
                    if(flag == 1) {                 
                        bit = bit >> 1; 
                        bit = bit | 0x80;
                    } 
                    else {                  
                        bit = bit >> 1;
                    }               
                }
                c[i] = (char) bit;  // represent the ASCII number by characters
                System.out.print(c[i]);
            }
        }
}

// Main.java

public class Main {
    
    public static void main(String[] args) throws Exception {
        try {
            BufferedImage coverImageText = ImageIO.read(new File("originalPic.png"));       
            String s = "Java is a popular programming language, created in 1995.";
            coverImageText = Steganography.embedText(coverImageText, s);                                // embed the secret information
            Steganography.extractText(ImageIO.read(new File("textEmbedded.png")), s.length()); // extract the secret information
        } catch(IOException e) {        
            System.out.print("Error: " + e);
        }   
    }
}

The problem is that it does extract most part correctly with exception of few characters. For this example in the console is displayed:

Extracting: Java is a popular progsamming langua'e, creaved in 1995.

I tried with different input texts but there are always some characters incorrectly extracted. The textEmbedded.png look like the original image with a bit different size as it should. Can someone please help me understand what is wrong here.

0

There are 0 answers