📄 encryptfile.java~6~
字号:
/**
* 使用流类隐藏数据
* 整体思路:我们需要将一些数据隐藏起来的时候,可以利用bmp图形文件,bmp图形文件有其图形文件的长度,存放在bmp文件的
* 头结构中,bmp文件的头结构位于bmp文件的起始部分,前两个字节是图形文件的类型,后续的字节描述了图形文件的
* 大小。
* 我们可以利用这个特性,在写入隐藏内容时,将内容附着在图形文件的尾部,此时不影响图形文件的正常的显示(因为
* 头结构中描述了图形文件的大小),在读取我们附着在尾部的数据时,只要跳过图形文件的大小,此时再读取得数据就
* 是我们的真实的数据了,这样,即使是别人看到这个文件,打开后只是普通的图形文件,我们隐藏私有信息的目的就达
* 到了。
* 这种技术在前一段时间是很流行的一种,甚至专门出了破解的软件,在此例中只演示了存入字符数据,如果存入的是字
* 节数据,请自行更改,应该使用字节流。
* */
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 + -