【问题标题】:Can't extract text in Steganography无法在隐写术中提取文本
【发布时间】:2014-08-19 07:16:28
【问题描述】:

我有一个代码可以使用 C# 中的速记法在图像上放置一个字符串值,使用这里的代码

http://www.codeproject.com/Tips/635715/Steganography-Simple-Implementation-in-Csharp

现在我必须在 android 端提取字符串。 这是我用于文本提取的 android 端代码

   private String extractText(Bitmap bmp) {
        // TODO Auto-generated method stub
        int colorUnitIndex = 0;
        int charValue = 0;

        // holds the text that will be extracted from the image
        String extractedText ="";

        for(int w=0;w<bmp.getHeight();w++)
        {
            for(int h=0;h<bmp.getWidth();h++)
            {
                int color=bmp.getPixel(h, w);
                green=Color.green(color);
                blue=Color.blue(color);
                red=Color.red(color);

                bred=(byte)red;
                bgreen=(byte)green;
                bblue=(byte)blue;

                // for each pixel, pass through its elements (RGB)
                for (int n = 0; n < 3; n++)
                {
                    switch (colorUnitIndex % 3)
                    {
                        case 0:
                            {
                                // get the LSB from the pixel element (will be pixel.R % 2)
                                // then add one bit to the right of the current character
                                // this can be done by (charValue = charValue * 2)
                                // replace the added bit (which value is by default 0) with
                                // the LSB of the pixel element, simply by addition
                                charValue = charValue * 2 + bred % 2;
                            } break;
                        case 1:
                            {
                                charValue = charValue * 2 + bgreen % 2;
                            } break;
                        case 2:
                            {
                                charValue = charValue * 2 + bblue % 2;
                            } break;
                    }

                    colorUnitIndex++;

                    // if 8 bits has been added, then add the current character to the result text
                    if (colorUnitIndex % 8 == 0)
                    {
                        // reverse? of course, since each time the process happens on the right (for simplicity)
                        charValue = reverseBits(charValue);

                        // can only be 0 if it is the stop character (the 8 zeros)
                        if (charValue == 0)
                        {
                            return extractedText;
                        }

                        // convert the character value from int to char
                        char c = (char)charValue;

                        // add the current character to the result text
                        extractedText += String.valueOf(c);
                    }
                }

            }

        }
        return extractedText;


    }

    private int reverseBits(int n) {
        // TODO Auto-generated method stub


         int result = 0;

            for (int i = 0; i < 8; i++)
            {
                result = result * 2 + n % 2;

                n /= 2;
            }

            return result;
    }

};

但我在 android 端没有得到正确的字符串。 不知道是什么问题。 有人可以帮忙吗?? 提前致谢。

【问题讨论】:

  • 您确定图像已正确传输到设备吗?你确定Bitmap格式没有字节序问题(发送前在.NET端检查几个Pixels的值,在系统的Java端检查相同的像素)?
  • 还将Java标签添加到您的问题中,因为它是部分代码转换问题。
  • 是的,我确信图像已正确传输到 android 设备。
  • 另外,当 UTF-16 编码实际需要 16 位时,我对“如果添加了 8 位”有一些保留。并乘以 2 代替位移。但问题是它在源示例中是一样的。我只想告诉你,那个 codeproject 隐写术示例在代码中比在算法中具有更多的隐写术。它需要一些清理和重构。
  • 尝试:1) 创建两个提取文本的桌面应用程序 - 一个在 C# 中(来自 CodeProject),另一个在 Java 中来自您的 android 代码 2) 创建一个带有隐藏文本的图像。 3)并行启动和调试这两个应用程序,同时从图像中提取第一个字节(8 位)或几个字节(只需使用 FileShare.Read 打开它) 4)如果它们以相同的方式运行 - 那么你的问题就在转换中数据(或 android 特性) 5) 否则很容易看出从 C# 到 Java 的代码转换在哪里误解了某些构造或方法。

标签: java c# android steganography


【解决方案1】:

我终于找到了解决方案 只需在循环中使用此代码,我就可以提取文本。

               result[b] = (byte)((result[b] << 1) | (buff[offset] & 1));

谢谢大家。

【讨论】:

    【解决方案2】:

    Java 没有无符号字节(如 c#)。

    int x = 176;
    byte y = (byte)x; // if you print y, the result is: -80.
    

    因此,在您的代码中,只要 RGB 值大于 127,它就会被解释为不同的值(-80 而不是 176)。

    该代码仅使用模块 2 检查最右边位的值,这当然可以在 int 上执行。所以你可以直接使用“green”、“blue”和“red”(去掉“bgreen”、“bblue”、“bred”):

    private static String extractText(BufferedImage bmp) 
    {
        int colorUnitIndex = 0;
        int charValue = 0;
    
        String extractedText ="";
    
        for(int i=0;i<bmp.getHeight();i++)
        {
          for(int j=0;j<bmp.getWidth();j++)
          {
            Color color = new Color(bmp.getRGB(j, i));
    
            int green=color.getGreen();
            int blue=color.getBlue();
            int red=color.getRed();
    
            // for each pixel, pass through its elements (RGB)
            for (int n = 0; n < 3; n++)
            {
              switch (colorUnitIndex % 3)
              {
                case 0:
                {
                  // get the LSB from the pixel element (will be pixel.R % 2)
                  // then add one bit to the right of the current character
                  // this can be done by (charValue = charValue * 2)
                  // replace the added bit (which value is by default 0) with
                  // the LSB of the pixel element, simply by addition
                  charValue = charValue * 2 + red % 2;
                } break;
                case 1:
                {
                  charValue = charValue * 2 + green % 2;
                } break;
                case 2:
                {
                  charValue = charValue * 2 + blue % 2;
                } break;
              }
    
              colorUnitIndex++;
    
              // if 8 bits has been added, then add the current character to the result text
              if (colorUnitIndex % 8 == 0)
              {
                // reverse? of course, since each time the process happens on the right (for simplicity)
                charValue = reverseBits(charValue);
    
                // can only be 0 if it is the stop character (the 8 zeros)
                if (charValue == 0)
                {
                  return extractedText;
                }
    
                // convert the character value from int to char
                char c = (char)charValue;
    
                // add the current character to the result text
                extractedText += String.valueOf(c);
              }
            }
          }
        }
        return extractedText;
      }
    

    【讨论】:

      猜你喜欢
      • 2011-09-27
      • 2015-01-20
      • 2013-10-06
      • 2013-04-21
      • 2017-02-03
      • 2014-07-11
      • 2020-03-12
      • 2013-03-17
      • 2014-10-31
      相关资源
      最近更新 更多