当前位置: 首页 > 面试题库 >

有损压缩中的隐写术(JAVA)

陈增
2023-03-14
问题内容

我有这个用于在Java的jpeg图像中编码数据。我将文本转换为二进制格式,并将其插入从(0,0)到(width,height)的每个像素的RGB的LSB(取决于用户选择的内容。1、2、3、4)

outer:
    for(int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            Color c = new Color(image.getRGB(j, i));

            int red = binaryToInteger(insertMessage(integerToBinary((int)(c.getRed())),numLSB));
            int green = binaryToInteger(insertMessage(integerToBinary((int)(c.getGreen())),numLSB));
            int blue = binaryToInteger(insertMessage(integerToBinary((int)(c.getBlue())),numLSB));

            Color newColor = new Color(red,green,blue);
            image.setRGB(j,i,newColor.getRGB());

        }
    }
    gui.appendStatus("Binarized message is: " + binarizedMessage);
    File output = new File(gui.getOutput()+".jpg");

    ImageIO.write(image, "png", output);

目前,即时通讯将其编写为png,并且效果很好,但我希望在jpeg中实现。我成功获取了png中的那些数据。但正如预期的那样,jpeg失败。

我能够解码所写图像中的隐藏位,并在选择了正确的LSB的情况下看到消息。

我目前正在阅读有关JPEG隐写技术的信息,但并不太清楚我应该如何启动它。我看过算法,也没有帮助我。

我看到了没有找到任何主类的代码。

我必须在应用程序中调用它吗?修改吗?我将如何解码?

这是我看到的代码的链接。


问题答案:

jpeg使用有损压缩方法来实现较小的文件大小。不幸的是,该方法直接影响(某些)像素的值,从而破坏了嵌入信息的方式。您需要以无损格式保存文件以避免这种问题,例如bmp或png。

Jpeg隐写术的代码编写有些复杂,但是概念很简单。您将需要编写jpeg编码器,或者已经使用一个编码器。您链接到的代码确实是一种编码器,只需稍作修改,就可以将其用于您的项目。

如果您想了解代码,可以阅读有关jpeg编码的维基百科文章。我将简要总结其一些关键步骤。

  • 将图像分成8x8块。
  • 在每一个上使用离散余弦变换(DCT)获得浮点DCT系数并将其量化为整数。
  • 使用霍夫曼编码和游程长度编码将量化系数存储到文件中。

第二步中的量化是有损比特,但是随后进行的所有操作都是无损的。因此,基本上,从第二步获取量化系数,使用隐写算法对其进行修改,然后继续第三步。

关于链接代码的实际修改。该Compress方法是您需要调用以将rgb图像存储到文件中的方法。它负责写头数据和压缩系数。您只需要在该WriteCompressedData方法中添加一些代码即可。现在要做的是循环遍历每个8x8图像块,应用dct并量化存储在中的系数dctArray3。然后将这些数据压缩写入文件。那是您必须进行干预的地方,dctArray3在致电之前进行修改Huf.HuffmanBlockEncoder

例如,假设您有一个秘密的字节数组,称为message,并且您希望将每个8x8块的一位嵌入特定系数的lsb中。

public void WriteCompressedData(BufferedOutputStream outStream, byte[] message) {
    byte currentByte;
    int nBytes = message.length;
    int iByte = 0;
    int iBit = 7;
    if (nBytes > 0) {
        currentByte = message[0];
    } else {
        currentByte = (byte) 0;
    }
    // Original method code up until the following line
    dctArray3 = dct.quantizeBlock(dctArray2, JpegObj.QtableNumber[comp]);
    // ******************** our stuff *******************
    if (iByte < nBytes) {
        int bit = (currentByte >> iBit) & 1;
        iBit--;
        if (iBit == -1) {
            iBit = 7;
            iByte++;
            if (iByte < nBytes) {
                currentByte = message[iByte];
            }
        }
        dctArray3[23] = (dctArray3[23] & 0xfffffffe) | bit;
    }
    // **************************************************
    Huf.HuffmanBlockEncoder(outStream, dctArray3, lastDCvalue[comp], JpegObj.DCtableNumber[comp], JpegObj.ACtableNumber[comp]);
    ...
}

解码是与此相反的,您可以读取DCT系数并使用适当的算法从中提取秘密。您将需要使用jpeg解码器,因此我只是从F5
Steganography
项目中借用了相关文件。具体来说,您需要文件ortega夹中的文件,然后可以像这样使用它。

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import ortega.HuffmanDecode;

public class Extract {
    private static byte[] deZigZag = {
            0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31,
            40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61,
            35, 36, 48, 49, 57, 58, 62, 63 };

    private static int[] extract(InputStream fis, int flength) throws IOException {
        byte[] carrier = new byte[flength];
        fis.read(carrier);
        HuffmanDecode hd = new HuffmanDecode(carrier);
        int[] coeff = hd.decode();
        return coeff;
    }

    public static void main(String[] args) {
        // run with argument the stego jpeg filename
        try {
            File f = new File(args[0]);
            FileInputStream fis = new FileInputStream(f);
            int[] coeff = extract(fis, (int) f.length());

            int idx = deZigZag[23];
            // The coeff array has all of the DCT coefficients in one big
            // array, so that the first 64 elements are the coefficients 
            // from the first block, the next 64 from the second and so on.
            //
            // idx is the position of the embedding DCT coefficient.
            // You can start with that and extract its lsb, then increment
            // by 64 to extract the next bit from the next "block" and so on.
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


 类似资料:
  • 本文向大家介绍有损压缩和无损压缩之间的区别,包括了有损压缩和无损压缩之间的区别的使用技巧和注意事项,需要的朋友参考一下 数据压缩是指将大文件缩小为较小大小的文件并可以再次将其解压缩为大文件的技术。有损压缩会将大文件恢复为原始格式,但会丢失一些数据,这是不明显的,而无损压缩会将大文件恢复为原始格式而不会丢失任何数据。 以下是有损压缩和无损压缩之间的一些重要区别。 序号 键 有损压缩 无损压缩 1 数

  • 这些是我正在使用的当前论点: 根据:http://www.imagemagick.org/script/command-line-options.php#define 和http://www.w3.org/tr/png-filters.html null 问题: 这是无损压缩吗?如果没有,错在哪里? 知道如何实现更好的无损压缩吗?

  • 本文向大家介绍C#无损压缩图片,包括了C#无损压缩图片的使用技巧和注意事项,需要的朋友参考一下 话不多说,请看代码: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!

  • 我需要压缩一个有几个灰色16bit图像(多页)的tif文件。我已经尝试使用ImageIO如下所示:使用Java ImageIO进行Tiff压缩最初,tif文件中的每个图像都来自另一个Tiff文件。当我想使用压缩机时,我有以下选项: null

  • 我正在使用Julia的ZipFile包来提取和处理csv文件。没问题,但是当我遇到zip文件中的zip文件时,我也想处理它,但是遇到了一个错误。 Julia ZipFile文档如下:https://zipfilejl.readthedocs.io/en/latest/ 对如何做到这一点有什么想法吗?

  • 我想知道我们可以在多大程度上进行无损数据压缩;我无法找到一个无损算法的在线模拟器来执行一些经验测试。我可以自己做一个,但不幸的是,我在这段时间没有足够的时间;我仍然对我的直觉感到好奇,我将解释一下。 让我们只看两种更流行的算法: