对文本文件加解密的方法很多,一种简单的加解密方法就是通过异或操作。即对明文a,进行a^k=b.b为得到的密文,当再次对b做b^k=a',此时a'=a;即解密。
补充知识点:
1.java中可以把字符a通过类型强制转换的形式转换a的unicode码或者是ascii码。
即:char a='c'; int d=a;//可以得到d即为'c'的ascii码。
或者通过char c = 'a '; byte b =(byte)c;也可以。
2.当对字符对应的ascii码进行了操作之后,可以再次通过类型的强制转换把字符的ascii码转换为char类型。
即: int a=97; char b=(char)a; //即可以得到97对应的字符
3.将String对象和字符相加可以直接用+.
即: String s=s+'k';
4.要把String中的某个字符转换为字符型可以用str.charAt(index),把整个String转换为一个字符数组可以用:str.toCharArray();把一个字符转换为String类型可以用String.valueOf('c')
5.关于Scanner的sc.next()和sc.nextLine()的区别
首先介绍next()和nextLine():
next()一定要读取到有效字符才可以结束输入。对输入的有效字符之前的空格/回车/tab等结束符会自动过滤掉,在输入有效字符之后,再次出现空格/回车/tab等结束符才会结束输入操作。(即:next()不能接收包括空格/tab等字符的输入)
nextLine()方法的结束符只有enter(回车),即nextLine()方法返回的是enter键之前的所有字符,可以得到带有空格/tab键在内的字符串。
6.concat()和+
concat()它表示在此对象字符后连接字符串参数字符而成的字符。
+可以把任意类型的参数连接起来。
注意的是:
当next()和nextLine()连用时,若先用nextLine(),接着用next()方法,结果会与想像的一样。
但是若先调用next()在调用nextLine()方法,则会因为next()过滤掉了最终输入的enter,而接下来的nextLine()会首先读取上面过滤掉的Enter,这样nextLine()会把这个Enter作为自己的结束符,结束输入。导致后者不能接收到有效字符串。
同样在nextDouble(),nextFloat(),nextInt()与nextLine()连用是也会存在这个问题。
代码:
编写加解密类(包括加密方法,解密方法):
package chuanshu;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.FileReader;
public class jiajiemi {
public void enFile(String f1,String f2,int key)throws Exception{
FileReader fin=new FileReader(f1.toString());
BufferedReader bin=new BufferedReader(fin);//读取f1
FileWriter fout=new FileWriter(f2.toString());//生成写入f2的对象
String f2Line;//将加密后的内容一行一行的写入到f2
String aline;//由f1读入的一行信息
String textline;//一行文本,将由f1读入的aline转换为String作为f2的一行写入
do{
aline=bin.readLine();//由bufferedREader读入一行信息
if(aline!=null){//读入的为一个对象
textline=new String(aline);
f2Line=jiami(textline,key);//加密当前文档
fout.write(f2Line.toString()+"
");//写入文件
}
}while(aline!=null);
bin.close();//先生成FileReader对象
fin.close();//在生成的BufferedReader对象
fout.close();//用到了文本输出对象FileWriter
}
public void deFile(String f1,String f2,int key)throws Exception{
FileReader bin=new FileReader(f1.toString());
BufferedReader fin=new BufferedReader(bin);
FileWriter fout=new FileWriter(f2.toString());
String f2line;
String aline;
String textline;
do{
aline=fin.readLine();//由f1读入一行
if(aline!=null){
textline=new String(aline);
f2line=jiemi(textline,key);
fout.write(f2line.toString()+"
");
}
}while(aline!=null);
bin.close();
fin.close();
fout.close();
}
public String jiami(String s,int key){
String str=new String();
int ch;
for(int i=0;i<s.length();i++){
ch=s.charAt(i)^(((int)Math.sqrt(key))%126+1);//加密s.charAt(i)获取i位置的字符,然后系统自动转换为了ascii码
if(ch==13){
ch=ch+1;//将回车符特殊处理
}
if(ch==10){
ch=ch+1;//换行符特殊处理
}
str=str+(char)ch;
//str.concat(String.valueOf((char)ch));//利用String.valueOf("char")把char类型转换为String
//上面的ch为int类型,这里先把acii码转换为char在转换为String
}
return str;
}
public String jiemi(String s,int key){
String line=new String();//声明解密后的一行的对象
int ch,temp;
for(int i=0;i<s.length();i++){
temp=s.charAt(i);
if(temp==14){
temp=temp-1;
}
if(temp==11){
temp=temp-1;
}
ch=temp^(((int)Math.sqrt(key))%126+1);//把((int)Math.sqrt(key))强制转换为int类型 解密
//line.concat(String.valueOf((char)ch));
line=line+(char)ch; //此处不知道为什么我用line.concat(String.valueOf((char)ch));的不出结果
//上面的ch为int类型,这里先把acii码转换为char在转换为String
}
return line;
}
}
主函数类:
先创建加解密对象,然后调用加解密方法;
package chuanshu;
import java.util.Scanner;
public class jiajiemimain {
public static void main(String[] args) throws Exception{
jiajiemi a=new jiajiemi();//生成加解密的类
Scanner sc=new Scanner(System.in);
System.out.println("===============================================");
System.out.println("1.加密;");
System.out.println("2.解密;");
System.out.println("===============================================");
System.out.println("请输入选择:(1-2)");
/*char b='a';
System.out.println(b);
int c=b;
System.out.println(c);
int m=c^(((int)Math.sqrt(2))%126+1);
System.out.println(m);
char d=(char)c;
System.out.println(d);
char e=(char)m;
System.out.println(e);
int key=sc.nextInt();
String s=sc.next();
int ch;
String str=new String();
for(int i=0;i<s.length();i++){
ch=s.charAt(i)^(((int)Math.sqrt(key))%126+1);
if(ch==13){
ch=ch+1;//将回车符特殊处理
}
if(ch==10){
ch=ch+1;//换行符特殊处理
}
// char l=(char)ch;
//str=str+l;
str=str+(char)ch;
}
System.out.println(str);
}*/ //此处主要是,当初我在加解密方法中用的str.concat(...)没有返回结果,然后自己一步步调试寻找结果的过程
//(包括理解整个加解密算法的过程)
int i=sc.nextInt();/////最终过滤掉了末尾的回车符
if(i==1){
System.out.println("请输入要加密的文件名,加密后的文件名以及加密密码:");
String f1=sc.next();//如果改用sc.nextLine();会接受上面nextInt()过滤掉的回车符,导致第一个参数f1不能输入
String f2=sc.next();//然后nextLine()接收了上面输入的参数f1
int key=sc.nextInt();//接收了上面输入的参数f2,导致不能再次输入 int类型,并且因为int接收了String报错
a.enFile(f1, f2, key);
}else if(i==2){
System.out.println("请输入要解密的文件名,解密后的文件名以及解密密码:");
String f1=sc.next();
String f2=sc.next();
int key=sc.nextInt();
a.deFile(f1, f2, key);
}else{
System.out.println("您输入序号不正确!");
}
}
}
结果:
文件f1的内容:
加密之后的结果文件2:
解密之后的结果文件3: