问题展示
在我们程序员的日常生活中,有时候往往想将一个非常简单的文件进行加密,使得他人不能看到里面真正的内容,这个文件内容可能是文本文件也可能是视频或者图像文件等。
我们大家都知道,在读取和写文件的时候都会使用到字节流(或者专门处理字符串的字符流),在这里就是用使用 字节流做一个简单的加密运算介绍。
本加密方法加密位置和原理
首先看一个对文件进行读写的操作(这是由于在加密的过程中,首先要使用这个步骤将文件的内容读取到内存中,然后才可以在内存中进行加密,最后还需要将加密之后的文件写入到本地磁盘)。
package cn.beixiansheng;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 使用字节流复制文件
* 这个可以后期作为加密的程序,从任意文件来生成密钥
*
* @author cn_newer
*/
public class Test1 {
public static void main(String[] args) {
// 在这里创建两个文件输出和输入流,用于操作文件
FileInputStream fis = null;
FileOutputStream fos = null;
try {
// 给文件的输入流进行赋值,括号里面的地址就是要操作的文件的地址
// 这里使用了相对路径,由于我在这里使用的是相对地址(当然可以使用绝对地址),
// 这个地址是相对于工程的根目录的
fis = new FileInputStream("data/1.wmv");
// 每次读取缓存的大小,每次先读取这么多的字节放在这个缓存中
// 然后再从这个缓存中写入本地
// 这里面也可以一般可以设置成每次加密的块的大小(或者这个大小的整数倍)
byte data[] = new byte[10 * 1024];
// 这个就是要输出的目录
fos = new FileOutputStream("data/out/1.wmv");
// 用于标记是否是读取到文件的末尾了,
// 在读入的字节流里面,使用某些读取函数,可以返回每次读取的字节数,
// 如果到了文件的结尾,不能再读取到内容,就返回-1
int len = -1;
// 将内容进行读入到指定大小的缓存块,直到读取到文件的结束为止
while (-1 != (len = fis.read(data))) {
// ===========================================
// =====重点的地方:在这里进行加密
// =====生成密钥的时候可以在这里取任意不同地方的密钥
// ===========================================
// 写入到本地文件中,写入的办法是从缓存块的开始到读取到文件的长度,
// 如果在这次的读取中没有达到文件的末尾的话,
// len就是缓存区所能放下的总的长度,
// 但是在完成前的最后一次读取中,能够读取到真正保存在里面的长度
fos.write(data, 0, len);
// 这个方法能够写到直接往磁盘里面写入,
// 而不是要等到关闭流(等其他时间)时间进行写入
fos.flush();
}
// 关闭文件的输出输入流
fis.close();
fos.close();
System.out.println("完成任务!!!");
} catch (IOException e) {
e.printStackTrace();
System.out.println("没有找到文件");
}
}
}
如果直接运行上面的代码,也就是在上面标注进行加密的地方不进行处理,也就是相当于将文件复制了一次。
但是在上面的代码里面将标注出可以的地方进行简单加密,可以对特定的字节或者特定位置的字节进行替换(需要是能可逆的变化),那么在写入的新文件里面,这样得到的新文件就是加密之后的文件,如果没有其他人知道你具体是怎样在这个地方进行的加密,几乎你的文件不可能被他人知道内容了。而在解密还原的时候只需要将这些变换就可以了。
举例展示加密算法实际应用
下面就举一个小的例子:
在这个小的例子中,主要是用来表示可以怎样加密的,也就是在上面注释缺失的代码里面可以使用的东西:
package cn.beixiansheng.t1;
import java.util.Scanner;
/**
* 这里简单演示一个使用异或加密的例子,本例直接使用命令行进行输入输出
* 由于两次异或等于原来的内容,
* 因此也可以使用这个进行直接的解密
* @author cn_newer
*
*/
public class Test2 {
public static void main(String[] args) {
//接收命令行输入的对象
Scanner in = new Scanner(System.in);
System.out.println("请输入字符串:");
//现在等待命令行输入,按Enter建结束
String s = in.nextLine();
//将输入的内容转换成字符数组
char[] s2 = s.toCharArray();
int size = s2.length;
//新建这个字符数组用于存放加密完成后字符串
char[] s3 = new char[size];
//这是一个简单的数字加密密码,
// 仅仅是为了演示,实际结果比这个复杂的多
// 在这里由于是使用char类型做异或运算,有效的密码是1~65535
char secret = (char)(4);
for(int i = 0;i<size;i++){
//将其中的每个字符做异或运算
s3[i] = (char) ((char)(s2[i])^secret);
}
String newString = new String(s3);
System.out.println("加密完的结果是:");
//并不是复制每次的结果都可以再做一次就还原的,
// 这是由于命令行将自己不认识的字符表示成“?”,这样就还原不了了;
// 但是如果是直接将结果保存在文件中,通过直接读写文件就没有问题
System.out.println(newString);
in.close();
}
}
如果要加密更复杂的内容,使用更复杂的加密算法即可。
对于非字符文件,可以使用加密里面的字节内容即可。
作者联系方式(微信号码):
邮箱:cn_newer@163.com