📄 encryptfile.java~1~
字号:
/**
*整体思路:
*我们需要将一些数据隐藏起来的时候,可以利BMP用图形文件
*BMP图形文件有其图形文件的长度,存放在BMP文件的头结构中
*BMP文件的头结构位于BMP文件的起始部分,前两个字节是图形文件的类型
*后续的字节描述了图形文件的大小。
*我们可以利用这个特性,在写入隐藏内容时,将内容附着在图形文件的尾部
*此时不影响图形文件的正常的显示(因为头结构中描述了图形文件的大小)
*在读取我们附着在尾部的数据时,只要跳过图形文件的大小,此时再读取得数据就是我们的
*真实的数据了,这样,即使是别人看到这个文件,打开后只是普通的图形文件
*我们隐藏私有信息的目的就达到了
*这种技术在前一段时间是很流行的一种,甚至专门出了破解的软件
*在此例中俺只演示了存入字符数据
*如果存入的是字节数据,请自行更改,应该使用字节流
*此例能流畅书写(不算计算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;
//在构造函数中获得文件的长度,备用
public EncryptFile(String fileName) throws IOException {
this.fileName = fileName;
this.fileLength = this.getBitMapLength(fileName);
}
private int getBitMapLength(String fileName) throws IOException {
//bmp文件的第三个字节开始描述bmp文件长度,注意低位在前,高位在后
//前两个字节描述文件类型是不是BMP文件
FileInputStream fin = new FileInputStream(fileName);
//跳过前两个字节
fin.skip(2);
//获取bmp图形文件的大小,此处看看就行了,如果将来不想搞
//图形处理,了解即可
//得到字节的十六进制值
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();
}
//返回转换为10进制的数字,表示文件的长度
return Integer.parseInt(highHigh + highLow + lowHigh + lowLow, 16);
}
//将数据写入bmp文件的尾部,这里只是简单地写入了,在实际使用时,还要加一些
//算法,对数据进行加解密
public void setData(String str) throws IOException {
//判断是否已经构造了PrintWriter,如是则不进行构造了
if (pw == null) {
//注意FileOutputStream的构造中的true表示附加数据
//PrintWriter构造中的true表示自动刷新,即:遇到println自动冲刷数据
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)));
}
//跳过图形文件,读取隐藏的内容
br.skip(this.fileLength - 2);
//因为字符串是不可更改的,所以使用了StringBuffer来提高效率
StringBuffer sb = new StringBuffer();
String strTemp = "";
//这个循环的写法应该没问题了吧?还看着别扭,
//自己写十遍!!!
while ( (strTemp = br.readLine()) != null) {
sb.append(strTemp + "\r\n");
}
//返回读到的数据
return sb.toString();
}
public void close() throws IOException {
//最后流类要关闭,强制自己养成这个习惯
if (br != null) {
br.close();
}
if (pw != null) {
pw.close();
}
}
public static void main(String[] args) {
//下面是进行使用写好的类,提供了用户的交互
//这个不是问题的核心
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:加入数据,2:读取数据");
String choice = keyIn.readLine();
if (choice.equals("1")) {
System.out.println("请输入要加入的数据,以end结束");
String data = "";
while (! (data = keyIn.readLine()).equalsIgnoreCase("end")) {
eFile.setData(data);
}
}
if (choice.equals("2")) {
System.out.println(eFile.getData());
}
//最后关闭了流类
eFile.close();
}
catch (Exception e) {
System.out.println(e);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -