?? encryptfile.java~1~
字號:
/**
*整體思路:
*我們需要將一些數(shù)據(jù)隱藏起來的時候,可以利BMP用圖形文件
*BMP圖形文件有其圖形文件的長度,存放在BMP文件的頭結(jié)構(gòu)中
*BMP文件的頭結(jié)構(gòu)位于BMP文件的起始部分,前兩個字節(jié)是圖形文件的類型
*后續(xù)的字節(jié)描述了圖形文件的大小。
*我們可以利用這個特性,在寫入隱藏內(nèi)容時,將內(nèi)容附著在圖形文件的尾部
*此時不影響圖形文件的正常的顯示(因為頭結(jié)構(gòu)中描述了圖形文件的大小)
*在讀取我們附著在尾部的數(shù)據(jù)時,只要跳過圖形文件的大小,此時再讀取得數(shù)據(jù)就是我們的
*真實的數(shù)據(jù)了,這樣,即使是別人看到這個文件,打開后只是普通的圖形文件
*我們隱藏私有信息的目的就達(dá)到了
*這種技術(shù)在前一段時間是很流行的一種,甚至專門出了破解的軟件
*在此例中俺只演示了存入字符數(shù)據(jù)
*如果存入的是字節(jié)數(shù)據(jù),請自行更改,應(yīng)該使用字節(jié)流
*此例能流暢書寫(不算計算BMP文件的長度的部分),你J2EE的第二章OK 了
*/
package ioconcealdata_a;
import java.io.*;
public class EncryptFile {
private BufferedReader br = null;
private PrintWriter pw = null;
private String fileName = null;
private int fileLength = 0;
//在構(gòu)造函數(shù)中獲得文件的長度,備用
public EncryptFile(String fileName) throws IOException {
this.fileName = fileName;
this.fileLength = this.getBitMapLength(fileName);
}
private int getBitMapLength(String fileName) throws IOException {
//bmp文件的第三個字節(jié)開始描述bmp文件長度,注意低位在前,高位在后
//前兩個字節(jié)描述文件類型是不是BMP文件
FileInputStream fin = new FileInputStream(fileName);
//跳過前兩個字節(jié)
fin.skip(2);
//獲取bmp圖形文件的大小,此處看看就行了,如果將來不想搞
//圖形處理,了解即可
//得到字節(jié)的十六進(jìn)制值
String lowLow = Integer.toHexString(fin.read());
String lowHigh = Integer.toHexString(fin.read());
String highHigh = Integer.toHexString(fin.read());
String highLow = Integer.toHexString(fin.read());
if (fin != null) {
fin.close();
}
//返回轉(zhuǎn)換為10進(jìn)制的數(shù)字,表示文件的長度
return Integer.parseInt(highHigh + highLow + lowHigh + lowLow, 16);
}
//將數(shù)據(jù)寫入bmp文件的尾部,這里只是簡單地寫入了,在實際使用時,還要加一些
//算法,對數(shù)據(jù)進(jìn)行加解密
public void setData(String str) throws IOException {
//判斷是否已經(jīng)構(gòu)造了PrintWriter,如是則不進(jìn)行構(gòu)造了
if (pw == null) {
//注意FileOutputStream的構(gòu)造中的true表示附加數(shù)據(jù)
//PrintWriter構(gòu)造中的true表示自動刷新,即:遇到println自動沖刷數(shù)據(jù)
pw = new PrintWriter(new FileOutputStream(fileName, true), true);
}
pw.println(str);
}
public String getData() throws IOException {
if (br == null) {
br = new BufferedReader(new InputStreamReader(new FileInputStream(this.
fileName)));
}
//跳過圖形文件,讀取隱藏的內(nèi)容
br.skip(this.fileLength - 2);
//因為字符串是不可更改的,所以使用了StringBuffer來提高效率
StringBuffer sb = new StringBuffer();
String strTemp = "";
//這個循環(huán)的寫法應(yīng)該沒問題了吧?還看著別扭,
//自己寫十遍!!!
while ( (strTemp = br.readLine()) != null) {
sb.append(strTemp + "\r\n");
}
//返回讀到的數(shù)據(jù)
return sb.toString();
}
public void close() throws IOException {
//最后流類要關(guān)閉,強(qiáng)制自己養(yǎng)成這個習(xí)慣
if (br != null) {
br.close();
}
if (pw != null) {
pw.close();
}
}
public static void main(String[] args) {
//下面是進(jìn)行使用寫好的類,提供了用戶的交互
//這個不是問題的核心
try {
BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in));
System.out.println("請輸入BMP文件的名字");
String fileName = keyIn.readLine();
EncryptFile eFile = new EncryptFile(fileName);
System.out.println("請輸入:1:加入數(shù)據(jù),2:讀取數(shù)據(jù)");
String choice = keyIn.readLine();
if (choice.equals("1")) {
System.out.println("請輸入要加入的數(shù)據(jù),以end結(jié)束");
String data = "";
while (! (data = keyIn.readLine()).equalsIgnoreCase("end")) {
eFile.setData(data);
}
}
if (choice.equals("2")) {
System.out.println(eFile.getData());
}
//最后關(guān)閉了流類
eFile.close();
}
catch (Exception e) {
System.out.println(e);
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -