数据结构(java语言描述)串与数组——文件加解密

对文本文件加解密的方法很多,一种简单的加解密方法就是通过异或操作。即对明文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:

原文地址:https://www.cnblogs.com/xleer/p/5337670.html