Java实现任意文件在bmp中的隐藏与导出

下载:http://download.csdn.net/source/493823

其实这个功能在C/C++上有N多实现方式,可惜一直没见人用Java写,上星期日看见有人在百度问,现在写一个发上来,偶就是手慢……

在实际帖代码前,我也先来点理论,因为很多人抗议我光写代码,没有理论基础……

BMP图像文件,即所谓的位图文件。在位图中,其表示方式是将一幅图像分割成栅格,栅格的每一点称为像素,每一个像素具有自己的RGB值,

以此构成图形。所以从本质上讲,一幅位图不过是由一系列像素点构成的点阵罢了。

位图文件支持4RLE(行程长度编码)以及8位和24位编码。本人在此类中只处理了24位格式。

24 BMP图像文件的结构特点为:(1)每个文件只能非压缩地存放一幅彩色图像;(2)文件头由54个字节的数据段组成,其中包含有该位图

文件的类型、大小、图像尺寸及打印格式等;(3)从第55个字节开始,是该文件的图像数据部分,数据的排列顺序以图像的左下角为起点,从

左到右、从下到上,每连续3个字节便描述图像一个像素点的颜色信息,这三个字节分别代表蓝、绿、红三基色在此像素中的亮度,若某连续三

个字节为:00H00HFFH,则表示该像素的颜色为纯红色。

 

要将文件隐藏在图片中,有两种模型方法可供参考:一是将文件附在载体图片之后,利用BMP文件的特殊性质(系统在读取 BMP文件的时候,是

读取它的第36个字节为文件长度,对超出这个长度的部分会忽略),将目标图片的二进制文件直接附着在载体之后,来实现文件的隐藏,此

方法简单易行,不会破坏载体与目标图片的任何信息,且对隐藏文件的大小没有限制,但隐蔽性有待加强。二是采用LSB算法,将所得目标文件

化整为零分别隐藏在载体的位图信息的每个字节的最低位,使得文件的隐蔽性大大提高,但可能因为载体的容量有限导致目标文件无法装入且

对隐藏文件的长度且有严格限制,此时一是用无损压缩的办法使隐藏文件变小,二是放大载体图像,三是增加在载体文件每字节存放的位数。

 

但这两种模型的优缺点在一定程度上可以互补,对于实际问题,可根据特定情况将以上两种想法结合起来,得到更理想的模型,即当载体图片

大小满足做法二的要求时,则按位加入,否则将剩余的二进制位按照第一种做法直接加在载体图片后。

 

1)模型1 ——尾部附加法。通过对BMP图像文件的数据结构的分析在BMP图像的头文件中有指示文件大小的数值bfSIZE。它指定了一般的图片

浏览器所能读取的范围。若不改变该数值的大小,则一般的图片浏览器只能够读取原文件。即便在该文件的尾部接上其他的文件,图片浏览器

所显示的仍然只是原文件。这就相当于把后续文件给屏蔽掉了,可以达到隐藏信息的目的。一旦图片被截获者截获,一般的图片浏览器对图片

的读取也只能进行到载体部分,目标图片不会被暴露出来,达到隐藏的效果。

 

2)模型2 ——内部嵌入法。对第一种模型的不足,即截获者可以用一些特殊方式发觉载体图片隐藏着一些信息,那么隐蔽性就大打折扣。通

过研究发现,对一幅用多比特值表示其灰度的图像来说,其中每个比特可看作表示了一个二值平面,也称作“位面”。“1幅灰度级用8bit表示

的图像有8个位面,一般用0代表最低位面,位面 7代表最高位面。基本上5个最高面含有视觉可见的有意义的信息,在其余的位面中几乎没有任

何视觉信息,这些位面所显示的只是图像中很细小的局部,在很多情况下,它们可看作噪声”正因为图像具有位面这种性质,因此信息往往隐

藏在不为人视觉所察觉的位置,这样位面就为信息隐藏提供了一种很好的实施方案。将信息隐藏在这些看似噪声的位置,其对图像的破坏就不

会太大,当然,在嵌入信息之前,首先要选择好信息具体加入的位面位置,不能将信息加入在存在图像视觉信息的位面上,因此,一般的LSB

法中,信息一般加在图像的后4位。

 

 

1)嵌入秘密信息的具体步骤:

 

第一步:读入载体文件,并显示它;

 

第二步:决定载体的LSB及嵌入的位数,本文采用嵌入图像中所有象素的最后一位,即第8位;

 

第三步:对载体图像做预处理,置其LSB0

 

第四步:将秘密信息以ACILL码的形式读入,并存储;

 

第五步:在每一个象素的第LSB位上,存储秘密信息的一个bit;

 

第六步:显示嵌入秘密文件的图像;

 

2)读取秘密信息的具体步骤:

 

第一步:读入含有秘密文件的图像;

 

第二步:得到每一个象素点的LSB位;

 

第三步:由每8LSB位组成一个ASILL还原秘密信息。

 

实现起来其实很简单,无论使用哪种理论模型,大体都是利用数据偏移罢了,偶用的内部嵌入法,大家可以根据自己的需要变更偶的代码,也

欢迎大家创造的隐藏方法,那位大侠有时间更改的话给偶也寄一份,我的Email:ceponline@yahoo.com.cn

 

本类从功能上讲,可以把任意文件(不能超过bmp文件大小)隐藏到BMP图片中,图片大小基本不变,浏览图片也看不出变化。当然,也可以把隐

藏在图片中的文件提取出来。

 

代码如下,由3个类构成:

 

BitmapInput.java

 

package org.loon.framework.test.encode;

 

import java.awt.image.BufferedImage;

 

/** *//**

 * <p>

 * Title: LoonFramework

 * </p>

 * <p>

 * Description:

 * </p>

 * <p>

 * Copyright: Copyright (c) 2007

 * </p>

 * <p>

 * Company: LoonFramework

 * </p>

 *

 * @author chenpeng

 * @emailceponline@yahoo.com.cn

 * @version 0.1

 */

public class BitmapInput ...{

 

    private BufferedImage _bmp;

 

    private int curX, curY, iRGB;

 

    private int bitsLeft;

 

    public BitmapInput(BufferedImage bmp) ...{

 

        curX = curY = iRGB = 0;

        this._bmp = bmp;

        bitsLeft = bmp.getHeight() * bmp.getWidth() * 3;

 

    }

 

 

    public BufferedImage getBufferedImage() ...{

        return _bmp;

    }

 

    public synchronized Object[] readByte(int body) ...{

        body = 0;

 

        if (bitsLeft < 8) ...{

            return new Object[] ...{ "false", "0" };

        }

        int bit = 0;

        int bits2Do = 8;

        for (; curX < _bmp.getWidth(); curX++) ...{

            if (curY >= _bmp.getHeight())

                curY = 0;

 

            for (; curY < _bmp.getHeight(); curY++) ...{

                if (bits2Do == 0) ...{

                    return new Object[] ...{ "true", String.valueOf(body) };

                }

                int rgb = _bmp.getRGB(curX, curY);

                int r = (rgb & 0x00ff0000) >> 16;

                int g = (rgb & 0x0000ff00) >> 8;

                int b = (rgb & 0x000000ff);

                while(true) ...{

                    switch (iRGB) ...{

                    case 0:

                        bit = (r & 1);

                        break;

 

                    case 1:

                        bit = (g & 1);

                        break;

 

                    case 2:

                        bit = (b & 1);

                        break;

                    }

 

                    --bits2Do;

                    --bitsLeft;

                    body |= (int) (bit << 7);

                    if (bits2Do != 0) ...{

                        body >>= 1;

                    }

 

                    if (iRGB == 2) ...{

                        iRGB = 0;

                        break;

                    }

                    iRGB++;

                    if (bits2Do == 0) ...{

                        return new Object[] ...{ "true", String.valueOf(body) };

                    }

                }

            }

        }

        return new Object[] ...{ "true", String.valueOf(body) };

    }

 

}

 

BitmapOutput.java

package org.loon.framework.test.encode;

 

import java.awt.image.BufferedImage;

 

/** *//**

 * <p>

 * Title: LoonFramework

 * </p>

 * <p>

 * Description:

 * </p>

 * <p>

 * Copyright: Copyright (c) 2007

 * </p>

 * <p>

 * Company: LoonFramework

 * </p>

 *

 * @author chenpeng

 * @emailceponline@yahoo.com.cn

 * @version 0.1

 */

public class BitmapOutput ...{

 

    private BufferedImage _bmp;

 

    private int curX, curY, iRGB;

 

    private int bitsLeft;

 

    private int r, g, b;

 

    public BitmapOutput(BufferedImage bmp) ...{

        this._bmp = bmp;

        curX = curY = iRGB = 0;

        bitsLeft  = (bmp.getHeight() * bmp.getWidth() * 3);

    }

 

 

    public BufferedImage getBufferedImage() ...{

        return _bmp;

    }

 

    public synchronized boolean writeByte(int body) ...{

        if (bitsLeft < 8)

            return false;

        int bits2Do = 8;

 

        for (; curX < _bmp.getWidth(); curX++) ...{

            if (curY >= _bmp.getHeight()) ...{

                curY = 0;

            }

 

            for (; curY < _bmp.getHeight(); curY++) ...{

                if (bits2Do == 0)

                    return true;

                int rgb = _bmp.getRGB(curX, curY);

                //转化为r,g,b格式

                r = (rgb & 0x00ff0000) >> 16;

                g = (rgb & 0x0000ff00) >> 8;

                b = (rgb & 0x000000ff);

                while (true) ...{

                    int curBit = (body & 1);

 

                    switch (iRGB) ...{

                    case 0:

                        r = (r & 0xFE);

                        r |= curBit;

                        break;

 

                    case 1:

                        g = (g & 0xFE);

                        g |= curBit;

                        break;

 

                    case 2:

                        b = (b & 0xFE);

                        b |= curBit;

                        break;

                    }

 

                    --bits2Do;

                    --bitsLeft;

                    body >>= 1;

                    //还原

                    rgb = (r << 16) | (g << 8) | b;

                    //重新注入

                    _bmp.setRGB(curX, curY, rgb);

                    if (iRGB == 2) ...{

                        iRGB = 0;

                        break;

                    }

                    iRGB++;

                    if (bits2Do == 0)

                        return true;

                }

            }

        }

        return true;

    }

}

 

BitmapExecute.java

package org.loon.framework.test.encode;

 

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.Iterator;

 

import javax.imageio.ImageIO;

import javax.imageio.ImageWriter;

import javax.imageio.stream.ImageOutputStream;

 

/** *//**

 * <p>

 * Title: LoonFramework

 * </p>

 * <p>

 * Description: 利用bmp文件进行数据的隐藏与导出

 * </p>

 * <p>

 * Copyright: Copyright (c) 2007

 * </p>

 * <p>

 * Company: LoonFramework

 * </p>

 *

 * @author chenpeng

 * @emailceponline@yahoo.com.cn

 * @version 0.1

 */

public class BitmapExecute ...{

 

    /** *//**

     * BufferedImage转化为bmp文件保存在指定位置

     *

     * @param image

     * @param file

     * @return

     */

    private static boolean saveBMP(BufferedImage image, File file) ...{

        // 格式化为bmp文件

        Iterator writers = ImageIO.getImageWritersByFormatName("bmp");

        ImageWriter writer = (ImageWriter) writers.next();

        ImageOutputStream ios = null;

        try ...{

            ios = ImageIO.createImageOutputStream(new FileOutputStream(file));

        } catch (IOException ioe) ...{

            return false;

        }

        writer.setOutput(ios);

        try ...{

            writer.write(image);

        } catch (IOException ioe) ...{

            return false;

        }

        return true;

    }

 

    /** *//**

     * 将数据文件隐藏入bmp文件中

     *

     * @param dataFileName

     * @param bmpFileName

     * @param outFileName

     * @return

     * @throws IOException

     */

    public static boolean DataSourceToBMP(String dataFileName,

            String bmpFileName, String outFileName) throws IOException ...{

        return DataSourceToBMP(new File(dataFileName), new File(bmpFileName),

                outFileName);

    }

 

    /** *//**

     * 将数据文件隐藏入bmp文件中

     *

     * @param dataFileName

     * @param bmpFileName

     * @param outFileName

     * @return

     * @throws IOException

     */

    public static boolean DataSourceToBMP(File dataFile, File bmpFile,

            String outFileName) throws IOException ...{

 

        FileInputStream dataStream = new FileInputStream(dataFile);

 

        BufferedImage bmp;

        try ...{

            bmp = ImageIO.read(bmpFile);

        } catch (Exception ex) ...{

            return false;

        }

        if (dataStream.available() == 0) ...{

            return false;

        }

        int maxByteStorage = (bmp.getHeight() * bmp.getWidth() * 3) / 8;

        // bmp文件必须较要隐藏的文件为大,否则无法注入文件

        if (maxByteStorage < dataStream.available() + 500) ...{

            return false;

        }

 

        BitmapOutput bmpWriter = new BitmapOutput(bmp);

        int dataSize = dataStream.available();

        try ...{

            for (int u = 0; u < 500; u++) ...{

                bmpWriter.writeByte(dataSize);

            }

            // 标记出完整数据

            bmpWriter.writeByte(91);

            for (int u = 0; u < dataSize; u++) ...{

                int result = dataStream.read();

                if (result == 91) ...{

                    bmpWriter.writeByte(123);

                } else if (result == 93) ...{

                    bmpWriter.writeByte(125);

                } else ...{

                    bmpWriter.writeByte(result);

                }

            }

            bmpWriter.writeByte(93);

        } catch (Exception ex) ...{

            ex.getStackTrace();

            return false;

        }

 

        try ...{

            File file = new File(outFileName);

            if (file.exists()) ...{

                file.delete();

            }

            // 保存BufferedImagebmp文件

            saveBMP(bmpWriter.getBufferedImage(), new File(outFileName));

        } catch (Exception ex) ...{

            ex.getStackTrace();

            return false;

        }

        return true;

    }

 

    /** *//**

     * bmp文件中导出隐藏数据(由于隐藏数据的方式不同,只对此类隐藏的有效)

     *

     * @param bmpFileName

     * @param outFName

     * @return

     * @throws IOException

     */

    public static boolean BMPToDataSource(String bmpFileName, String outFName)

            throws IOException ...{

        return BMPToDataSource(new File(bmpFileName), outFName);

    }

 

    /** *//**

     * bmp文件中导出隐藏数据(由于隐藏数据的方式不同,只对此类隐藏的有效)

     *

     * @param bmpFile

     * @param outFName

     * @return

     * @throws IOException

     */

    public static boolean BMPToDataSource(File bmpFile, String outFName)

            throws IOException ...{

        BufferedImage image = ImageIO.read(bmpFile);

        BitmapInput bmpReader;

 

        try ...{

            bmpReader = new BitmapInput(image);

        } catch (Exception ex) ...{

            return false;

        }

        FileOutputStream outStream;

        try ...{

            File file = new File(outFName);

            if (!file.exists()) ...{

                file.createNewFile();

            }

            outStream = new FileOutputStream(file);

        } catch (Exception ex) ...{

            return false;

        }

        int dataSize = 0;

        int outByte = 0;

        int count = 0;

        try ...{

            for (int u = 0; u < 500; u++) ...{

                // 以对象数组返回body和验证布尔值

                Object[] object = bmpReader.readByte(outByte);

                boolean header = Boolean.parseBoolean((String) object[0]);

                outByte = Integer.parseInt((String) object[1]);

                if (!header) ...{

                    throw new Exception();

                }

                dataSize |= (int) (outByte << 8 * 3);

                if (u != 3) ...{

                    dataSize >>= 8;

                }

            }

 

            for (int u = 0; u < dataSize; u++) ...{

 

                Object[] object = bmpReader.readByte(outByte);

                boolean header = Boolean.parseBoolean((String) object[0]);

                outByte = Integer.parseInt((String) object[1]);

                if (!header) ...{

                    throw new Exception();

                }

                if (outByte == 93) ...{

                    return true;

                }

                if (outByte == 91) ...{

                    count += 1;

                }

 

                if (count > 0) ...{

                    if (outByte == 123) ...{

                        outStream.write(91);

                    } else if (outByte != 91) ...{

                        outStream.write(outByte);

                    }

                }

            }

        } catch (Exception ex) ...{

            return false;

        } finally ...{

            try ...{

                outStream.flush();

                outStream.close();

                outStream = null;

            } catch (IOException e) ...{

                e.printStackTrace();

            }

        }

 

        return true;

    }

 

}

 更正 BitmapExecute.java :
/**
 * Copyright 2008
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 *
 * @project loonframework
 * @author chenpeng 
 * @email:ceponline@yahoo.com.cn
 * @version 0.1
 */
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;

public class BitmapExecute {

    /**
     * 将BufferedImage转化为bmp文件保存在指定位置
     *
     * @param image
     * @param file
     * @return
     */
    private static boolean saveBMP(BufferedImage image, File file) {
        // 格式化为bmp文件
        Iterator writers = ImageIO.getImageWritersByFormatName("bmp");
        ImageWriter writer = (ImageWriter) writers.next();
        ImageOutputStream ios = null;
        try {
            ios = ImageIO.createImageOutputStream(new FileOutputStream(file));
            writer.setOutput(ios);
            try {
                writer.write(image);
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } finally {
                ios.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }


    /**
     * 将数据文件隐藏入bmp文件中
     *
     * @param dataFileName
     * @param bmpFileName
     * @param outFileName
     * @return
     * @throws IOException
     */
    public static boolean DataSourceToBMP(String dataFileName,
            String bmpFileName, String outFileName) throws IOException {
        return DataSourceToBMP(new File(dataFileName), new File(bmpFileName),
                outFileName);
    }


    /**
     * 将数据文件隐藏入bmp文件中
     *
     * @param dataFileName
     * @param bmpFileName
     * @param outFileName
     * @return
     * @throws IOException
     */
    public static boolean DataSourceToBMP(File dataFile, File bmpFile,
            String outFileName) throws IOException {

        FileInputStream dataStream = new FileInputStream(dataFile);

        BufferedImage bmp;
        try {
            bmp = ImageIO.read(bmpFile);
        } catch (Exception ex) {
            return false;
        }
        // 获得要求隐藏文件字节数
        int dataSize = dataStream.available();
        if (dataSize == 0) {
            return false;
        }
        // 本图片允许的最大存储空间字节数
        int maxByteStorage = (bmp.getHeight() * bmp.getWidth() * 3) / 8;
        // 检查图片空间是否够用
        if (dataSize > maxByteStorage) {
            throw new RuntimeException(
                    ("Can be hidden space=" + maxByteStorage / 1024
                            + "KB! However,hidden files=" + dataSize / 1024 + "KB!")
                            .intern());
        }
        // 读取图片文件
        BitmapOutput bmpWriter = new BitmapOutput(bmp);
        try {
            // 将隐藏数据宽度转为byte[]保存
            byte[] size = IntengerToBytes(dataSize);
            // 在bmp文件中写入隐藏文件大小
            for (int u = 0; u < size.length; u++) {
                bmpWriter.writeByte((byte) size[u]);
            }
            // 输入隐藏数据
            for (int u = 0; u <=dataSize; u++) {
                bmpWriter.writeByte(dataStream.read());
            }
        } catch (Exception ex) {
            ex.getStackTrace();
            return false;
        } finally {
            dataStream.close();
        }

        try {
            File file = new File(outFileName);
            if (file.exists()) {
                file.delete();
            }
            // 保存BufferedImage为bmp文件
            saveBMP(bmpWriter.getBufferedImage(), new File(outFileName));

        } catch (Exception ex) {
            ex.getStackTrace();
            return false;
        }

        return true;
    }

    /**
     * 从bmp文件中导出隐藏数据(由于隐藏数据的方式不同,只对此类隐藏的有效)
     *
     * @param bmpFileName
     * @param outFName
     * @return
     * @throws IOException
     */
    public static boolean BMPToDataSource(String bmpFileName, String outFName)
            throws IOException {
        return BMPToDataSource(new File(bmpFileName), outFName);
    }

    /**
     * 转换整形数据为byte[]
     *
     * @param number
     * @return
     */
    final private synchronized static byte[] IntengerToBytes(final int number) {
        byte[] bytes = new byte[4];
        for (int i = 0; i < 4; i++) {
            bytes[i] = (byte) ((number >> (i * 8)) & 0xff);
        }
        return bytes;
    }

    /**
     * 将单独byte转为整形,负值转正
     *
     * @param bit
     * @return
     */
    final private static int toInteger(final byte bit) {
        if (bit >= 0) {
            return (int) bit;
        } else {
            return (int) (bit + 256);
        }
    }

    /**
     * 将byte[]转为整形
     *
     * @param bytes
     * @return
     */
    final private static int bytesForToInt(final byte[] bytes) {
        if (bytes.length != 4) {
            return 0;
        }
        int result = 0;
        try {
            result = toInteger(bytes[0]);
            result = (result << 8) + toInteger(bytes[1]);
            result = (result << 8) + toInteger(bytes[2]);
            result = (result << 8) + toInteger(bytes[3]);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 从bmp文件中导出隐藏数据(由于隐藏数据的方式不同,只对此类隐藏的有效)
     *
     * @param bmpFile
     * @param outFName
     * @return
     * @throws IOException
     */
    public static boolean BMPToDataSource(File bmpFile, String outFName)
            throws IOException {
        BufferedImage image = ImageIO.read(bmpFile);
        BitmapInput bmpReader;

        try {
            bmpReader = new BitmapInput(image);
        } catch (Exception ex) {
            return false;
        }
        FileOutputStream outStream;
        try {
            File file = new File(outFName);
            if (!file.exists()) {
                file.createNewFile();
            }
            outStream = new FileOutputStream(file);
        } catch (Exception ex) {
            return false;
        }
        byte[] number = new byte[4];
        int dataSize = 0;
        int outByte = 0;
        try {

            for (int u = number.length - 1; u > 0; u--) {
                // 以对象数组返回body和验证布尔值
                Object[] object = bmpReader.readByte(outByte);
                boolean header = Boolean.parseBoolean((String) object[0]);
                outByte = Integer.parseInt((String) object[1]);
                if (!header) {
                    throw new Exception();
                }
                number[u] = (byte) outByte;
            }
            // 将byte[]转回int形式的隐藏文件大小
            dataSize = bytesForToInt(number);
            // 将隐藏文件读出
            for (int u = 0; u <=dataSize; u++) {
                Object[] object = bmpReader.readByte(outByte);
                boolean header = Boolean.parseBoolean((String) object[0]);
                outByte = Integer.parseInt((String) object[1]);
                if (!header) {
                    throw new Exception();
                }
                // 第一位不读
                if (u != 0) {
                    outStream.write(outByte);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        } finally {
            try {
                outStream.flush();
                outStream.close();
                outStream = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return true;
    }

    public static void main(String[] args) {
        try {
            BitmapExecute.DataSourceToBMP(new File("c://book.txt"), new File(
                    "c://abc.bmp"), "c://testhide.bmp");
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BitmapExecute.BMPToDataSource(new File("c://testhide.bmp"),
                    "c://test.mid");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

 

测试用类(bmp文件等请自行准备)BMPHiedData.java

package org.loon.framework.test.encode;

 

import java.io.IOException;

 

/** *//**

 * <p>Title: LoonFramework</p>

 * <p>Description:利用bmp文件隐藏数据</p>

 * <p>Copyright: Copyright (c) 2007</p>

 * <p>Company: LoonFramework</p>

 * @author chenpeng 

 * @emailceponline@yahoo.com.cn

 * @version 0.1

 */

public class BMPHiedData ...{

 

    public static void main(String[]args)...{

        //导出为bmp

        try ...{

            //参数分别为:

            //1.要隐藏的数据

            //2.隐藏数据用图

            //3.导出位置

            BitmapExecute.DataSourceToBMP( "c:/test/txt.txt","c:/test/12193.BMP", "c:/test/test.bmp");

        } catch (IOException e) ...{

            e.printStackTrace();

        }

        //导出bmp中隐藏的数据

        try ...{

//            参数分别为:

            //1.隐藏数据用图

            //2.导出数据位置

            BitmapExecute.BMPToDataSource("c:/test/test.bmp", "c:/test/txt_test.txt");

        } catch (IOException e) ...{

            e.printStackTrace();

        }

    }

   

}

 

 

这时神不知鬼不觉,我们看似单纯的bmp文件,已经隐藏起了很多[邪恶][不可告人]的秘密。

 

————————————————————————————————————

 

顺便说一下,本人挺吝啬的,将写好的函数打了个对折才发出来(比如隐藏多文件,加密等,偶写了,就是不发^^),但也够用了……本意是

希望是大家都能帮我改进^_^。其实强化功能也很简单,只不过是数据存储格式的变化及性能优化罢了。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 29
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值