Java 隐写术错误输出

问题描述 投票:0回答:1

我想学习 Java 中的隐写术,并在 github 上找到了一个存储库,它看起来很简单,可以从中学习:https://github.com/tigerlyb/Steganography-in-Java。我在文本嵌入和提取方面遇到问题 - 由于某种原因,某些字符被错误提取。我无法找出代码中的错误,因为它看起来是正确的,并且错误字符的位置似乎是随机的。

这是我之前提到的存储库中的代码:

// 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);
        }   
    }
}

问题是它确实正确提取了大部分字符,但少数字符除外。对于此示例,控制台中显示:

摘录:Java 是一种流行的编程语言,创建于 1995 年。

我尝试使用不同的输入文本,但总是有一些字符提取不正确。 textEmbedded.png 看起来像原始图像,但大小略有不同。有人可以帮我理解这里出了什么问题吗?

java steganography
1个回答
0
投票

我对其进行了一些编辑,尽管我不确定为什么前一个不起作用......这个对我有用:

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

import javax.imageio.ImageIO;

public class Steganography {
    // embed secret information/TEXT into a "cover image"
    public static void embedText(BufferedImage image, String s, String fileName) throws Exception {
        int n = s.length();

        if (n * 8 > image.getWidth() * image.getHeight()) {
            throw new Exception("The provided text is too large to be embedded in the image.");
        }

        int x = 0;
        int y = 0;

        for (int i = 0; i < n; i++) { // for every char in string
            char c = s.charAt(i);
            int binaryNum = (int) c; // get ASCII value
            for (int j = 0; j < 8; j++) { // write every bit from binaryNum

                int bit = binaryNum & 0x00000001; // take LSB
                binaryNum = binaryNum >> 1; // move to next digit

                int colorByte = image.getRGB(x, y);

                if (bit == 1) {
                    image.setRGB(x, y, colorByte | 0x00000001);
                } else {
                    image.setRGB(x, y, colorByte & 0xFFFFFFFE);
                }
                
                x++;
                if (x >= image.getWidth()) {
                    x = 0;
                    y++;
                }

            }
        }
        System.out.println();
        File outputfile = new File(fileName);   
        ImageIO.write(image, "png", outputfile);
    }
        
        // extract secret information/Text from a "cover image"
        public static void extractText(BufferedImage image, int length) {
            int x = 0, y = 0;
            
            for (int i = 0; i< length; i++) {
                int binaryNum = 0;
                for (int j = 0; j<8; j++) {
                    int colorByte = image.getRGB(x, y);
                    int bit = colorByte & 0x00000001;
                    binaryNum = binaryNum >> 1;
                    if (bit == 1) {
                        binaryNum = binaryNum | 0x80;
                    }
                    
                    
                    x++;
                    if (x >= image.getWidth()) {
                       x = 0;
                       y++;
                    }

                }
                
                char c = (char) binaryNum;  
                System.out.print(c);  
            }
        }
}
© www.soinside.com 2019 - 2024. All rights reserved.