下載:http://download.csdn.net/source/493823
其實(shí)這個(gè)功能在C/C++上有N多實(shí)現(xiàn)方式,可惜一直沒見人用Java寫,上星期日看見有人在百度問,現(xiàn)在寫一個(gè)發(fā)上來,偶就是手慢……
在實(shí)際帖代碼前,我也先來點(diǎn)理論,因?yàn)楹芏嗳丝棺h我光寫代碼,沒有理論基礎(chǔ)……
BMP圖像文件,即所謂的位圖文件。在位圖中,其表示方式是將一幅圖像分割成柵格,柵格的每一點(diǎn)稱為像素,每一個(gè)像素具有自己的RGB值,
以此構(gòu)成圖形。所以從本質(zhì)上講,一幅位圖不過是由一系列像素點(diǎn)構(gòu)成的點(diǎn)陣罷了。
位圖文件支持4位RLE(行程長度編碼)以及8位和24位編碼。本人在此類中只處理了24位格式。
24 位BMP圖像文件的結(jié)構(gòu)特點(diǎn)為:(1)每個(gè)文件只能非壓縮地存放一幅彩色圖像;(2)文件頭由54個(gè)字節(jié)的數(shù)據(jù)段組成,其中包含有該位圖
文件的類型、大小、圖像尺寸及打印格式等;(3)從第55個(gè)字節(jié)開始,是該文件的圖像數(shù)據(jù)部分,數(shù)據(jù)的排列順序以圖像的左下角為起點(diǎn),從
左到右、從下到上,每連續(xù)3個(gè)字節(jié)便描述圖像一個(gè)像素點(diǎn)的顏色信息,這三個(gè)字節(jié)分別代表藍(lán)、綠、紅三基色在此像素中的亮度,若某連續(xù)三
個(gè)字節(jié)為:00H,00H,FFH,則表示該像素的顏色為純紅色。
要將文件隱藏在圖片中,有兩種模型方法可供參考:一是將文件附在載體圖片之后,利用BMP文件的特殊性質(zhì)(系統(tǒng)在讀取 BMP文件的時(shí)候,是
讀取它的第3~6個(gè)字節(jié)為文件長度,對超出這個(gè)長度的部分會忽略),將目標(biāo)圖片的二進(jìn)制文件直接附著在載體之后,來實(shí)現(xiàn)文件的隱藏,此
方法簡單易行,不會破壞載體與目標(biāo)圖片的任何信息,且對隱藏文件的大小沒有限制,但隱蔽性有待加強(qiáng)。二是采用LSB算法,將所得目標(biāo)文件
化整為零分別隱藏在載體的位圖信息的每個(gè)字節(jié)的最低位,使得文件的隱蔽性大大提高,但可能因?yàn)檩d體的容量有限導(dǎo)致目標(biāo)文件無法裝入且
對隱藏文件的長度且有嚴(yán)格限制,此時(shí)一是用無損壓縮的辦法使隱藏文件變小,二是放大載體圖像,三是增加在載體文件每字節(jié)存放的位數(shù)。
但這兩種模型的優(yōu)缺點(diǎn)在一定程度上可以互補(bǔ),對于實(shí)際問題,可根據(jù)特定情況將以上兩種想法結(jié)合起來,得到更理想的模型,即當(dāng)載體圖片
大小滿足做法二的要求時(shí),則按位加入,否則將剩余的二進(jìn)制位按照第一種做法直接加在載體圖片后。
(1)模型1 ——尾部附加法。通過對BMP圖像文件的數(shù)據(jù)結(jié)構(gòu)的分析在BMP圖像的頭文件中有指示文件大小的數(shù)值bfSIZE。它指定了一般的圖片
瀏覽器所能讀取的范圍。若不改變該數(shù)值的大小,則一般的圖片瀏覽器只能夠讀取原文件。即便在該文件的尾部接上其他的文件,圖片瀏覽器
所顯示的仍然只是原文件。這就相當(dāng)于把后續(xù)文件給屏蔽掉了,可以達(dá)到隱藏信息的目的。一旦圖片被截獲者截獲,一般的圖片瀏覽器對圖片
的讀取也只能進(jìn)行到載體部分,目標(biāo)圖片不會被暴露出來,達(dá)到隱藏的效果。
(2)模型2 ——內(nèi)部嵌入法。對第一種模型的不足,即截獲者可以用一些特殊方式發(fā)覺載體圖片隱藏著一些信息,那么隱蔽性就大打折扣。通
過研究發(fā)現(xiàn),對一幅用多比特值表示其灰度的圖像來說,其中每個(gè)比特可看作表示了一個(gè)二值平面,也稱作“位面”。“1幅灰度級用8bit表示
的圖像有8個(gè)位面,一般用0代表最低位面,位面 7代表最高位面。基本上5個(gè)最高面含有視覺可見的有意義的信息,在其余的位面中幾乎沒有任
何視覺信息,這些位面所顯示的只是圖像中很細(xì)小的局部,在很多情況下,它們可看作噪聲”正因?yàn)閳D像具有位面這種性質(zhì),因此信息往往隱
藏在不為人視覺所察覺的位置,這樣位面就為信息隱藏提供了一種很好的實(shí)施方案。將信息隱藏在這些看似噪聲的位置,其對圖像的破壞就不
會太大,當(dāng)然,在嵌入信息之前,首先要選擇好信息具體加入的位面位置,不能將信息加入在存在圖像視覺信息的位面上,因此,一般的LSB算
法中,信息一般加在圖像的后4位。
(1)嵌入秘密信息的具體步驟:
第一步:讀入載體文件,并顯示它;
第二步:決定載體的LSB及嵌入的位數(shù),本文采用嵌入圖像中所有象素的最后一位,即第8位;
第三步:對載體圖像做預(yù)處理,置其LSB為0;
第四步:將秘密信息以ACILL碼的形式讀入,并存儲;
第五步:在每一個(gè)象素的第LSB位上,存儲秘密信息的一個(gè)bit;
第六步:顯示嵌入秘密文件的圖像;
(2)讀取秘密信息的具體步驟:
第一步:讀入含有秘密文件的圖像;
第二步:得到每一個(gè)象素點(diǎn)的LSB位;
第三步:由每8個(gè)LSB位組成一個(gè)ASILL還原秘密信息。
實(shí)現(xiàn)起來其實(shí)很簡單,無論使用哪種理論模型,大體都是利用數(shù)據(jù)偏移罷了,偶用的內(nèi)部嵌入法,大家可以根據(jù)自己的需要變更偶的代碼,也
歡迎大家創(chuàng)造的隱藏方法,那位大俠有時(shí)間更改的話給偶也寄一份,我的Email:ceponline@yahoo.com.cn。
本類從功能上講,可以把任意文件(不能超過bmp文件大小)隱藏到BMP圖片中,圖片大小基本不變,瀏覽圖片也看不出變化。當(dāng)然,也可以把隱
藏在圖片中的文件提取出來。
代碼如下,由3個(gè)類構(gòu)成:
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
* @email:ceponline@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
* @email:ceponline@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);
//轉(zhuǎn)化為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文件進(jìn)行數(shù)據(jù)的隱藏與導(dǎo)出
* </p>
* <p>
* Copyright: Copyright (c) 2007
* </p>
* <p>
* Company: LoonFramework
* </p>
*
* @author chenpeng
* @email:ceponline@yahoo.com.cn
* @version 0.1
*/
public class BitmapExecute ...{
/** *//**
* 將BufferedImage轉(zhuǎn)化為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;
}
/** *//**
* 將數(shù)據(jù)文件隱藏入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);
}
/** *//**
* 將數(shù)據(jù)文件隱藏入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);
}
// 標(biāo)記出完整數(shù)據(jù)
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();
}
// 保存BufferedImage為bmp文件
saveBMP(bmpWriter.getBufferedImage(), new File(outFileName));
} catch (Exception ex) ...{
ex.getStackTrace();
return false;
}
return true;
}
/** *//**
* 從bmp文件中導(dǎo)出隱藏?cái)?shù)據(jù)(由于隱藏?cái)?shù)據(jù)的方式不同,只對此類隱藏的有效)
*
* @param bmpFileName
* @param outFName
* @return
* @throws IOException
*/
public static boolean BMPToDataSource(String bmpFileName, String outFName)
throws IOException ...{
return BMPToDataSource(new File(bmpFileName), outFName);
}
/** *//**
* 從bmp文件中導(dǎo)出隱藏?cái)?shù)據(jù)(由于隱藏?cái)?shù)據(jù)的方式不同,只對此類隱藏的有效)
*
* @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++) ...{
// 以對象數(shù)組返回body和驗(yàn)證布爾值
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;
}
}
/**
* 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轉(zhuǎn)化為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;
}
/**
* 將數(shù)據(jù)文件隱藏入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);
}
/**
* 將數(shù)據(jù)文件隱藏入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;
}
// 獲得要求隱藏文件字節(jié)數(shù)
int dataSize = dataStream.available();
if (dataSize == 0) {
return false;
}
// 本圖片允許的最大存儲空間字節(jié)數(shù)
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 {
// 將隱藏?cái)?shù)據(jù)寬度轉(zhuǎn)為byte[]保存
byte[] size = IntengerToBytes(dataSize);
// 在bmp文件中寫入隱藏文件大小
for (int u = 0; u < size.length; u++) {
bmpWriter.writeByte((byte) size[u]);
}
// 輸入隱藏?cái)?shù)據(jù)
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文件中導(dǎo)出隱藏?cái)?shù)據(jù)(由于隱藏?cái)?shù)據(jù)的方式不同,只對此類隱藏的有效)
*
* @param bmpFileName
* @param outFName
* @return
* @throws IOException
*/
public static boolean BMPToDataSource(String bmpFileName, String outFName)
throws IOException {
return BMPToDataSource(new File(bmpFileName), outFName);
}
/**
* 轉(zhuǎn)換整形數(shù)據(jù)為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;
}
/**
* 將單獨(dú)byte轉(zhuǎn)為整形,負(fù)值轉(zhuǎn)正
*
* @param bit
* @return
*/
final private static int toInteger(final byte bit) {
if (bit >= 0) {
return (int) bit;
} else {
return (int) (bit + 256);
}
}
/**
* 將byte[]轉(zhuǎn)為整形
*
* @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文件中導(dǎo)出隱藏?cái)?shù)據(jù)(由于隱藏?cái)?shù)據(jù)的方式不同,只對此類隱藏的有效)
*
* @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--) {
// 以對象數(shù)組返回body和驗(yàn)證布爾值
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[]轉(zhuǎn)回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文件等請自行準(zhǔn)備),BMPHiedData.java:
package org.loon.framework.test.encode;
import java.io.IOException;
/** *//**
* <p>Title: LoonFramework</p>
* <p>Description:利用bmp文件隱藏?cái)?shù)據(jù)</p>
* <p>Copyright: Copyright (c) 2007</p>
* <p>Company: LoonFramework</p>
* @author chenpeng
* @email:ceponline@yahoo.com.cn
* @version 0.1
*/
public class BMPHiedData ...{
public static void main(String[]args)...{
//導(dǎo)出為bmp
try ...{
//參數(shù)分別為:
//1.要隱藏的數(shù)據(jù)
//2.隱藏?cái)?shù)據(jù)用圖
//3.導(dǎo)出位置
BitmapExecute.DataSourceToBMP( "c:/test/txt.txt","c:/test/12193.BMP", "c:/test/test.bmp");
} catch (IOException e) ...{
e.printStackTrace();
}
//導(dǎo)出bmp中隱藏的數(shù)據(jù)
try ...{
// 參數(shù)分別為:
//1.隱藏?cái)?shù)據(jù)用圖
//2.導(dǎo)出數(shù)據(jù)位置
BitmapExecute.BMPToDataSource("c:/test/test.bmp", "c:/test/txt_test.txt");
} catch (IOException e) ...{
e.printStackTrace();
}
}
}
這時(shí)神不知鬼不覺,我們看似單純的bmp文件,已經(jīng)隱藏起了很多[邪惡]、[不可告人]的秘密。
————————————————————————————————————
順便說一下,本人挺吝嗇的,將寫好的函數(shù)打了個(gè)對折才發(fā)出來(比如隱藏多文件,加密等,偶寫了,就是不發(fā)^^),但也夠用了……本意是
希望是大家都能幫我改進(jìn)^_^。其實(shí)強(qiáng)化功能也很簡單,只不過是數(shù)據(jù)存儲格式的變化及性能優(yōu)化罷了。
浙公網(wǎng)安備 33010602011771號