⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encryptfile.java~2~

📁 使用流类隐藏数据(使用流类将我们的数据隐藏到BMP图形文件中
💻 JAVA~2~
字号:
/**
 * 整体思路:我们需要将一些数据隐藏起来的时候,可以利用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 + -