java-通过异或(xor)实现快速加解密的方法

java-通过异或(xor)实现快速加解密的方法

一、背景

首次接触异或加解密最早是在宽带不普及的时候,当时用的是某个在线音乐软件看MV,上网不易想着把MV下载下来,日后离线看。
可是在缓存目录把视频复制到其它目录后,发现不使用他们的播放器还无法播放。
查了下当时有对各家视频的转码程序,找个个试了下,直接转码成功。
当时也比较好奇,所以查了下相关资料。发现其实逻辑挺简单就是使用了一个固定值(暂定37吧),对流文件的每个字节执行“异或”运算。
对明文第一次与37异或后的值就是密文了,对密文再次与37异或,就能把它变回明文。
当时也没有深究原因,能用就完了呗!最近遇到个功能需要实现对大文件的快速加解密,脑海里突然蹦出来了这个算法。

二、异或定义

  • 运算规则
    • 如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
  • 更容易记忆的规则(半加运算)
    • 异或也叫半加运算,其运算法则相当于不带进位的二进制加法:
    • 二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位。
    • 所以异或常被认作不进位加法。

异或不常用,几天不不碎碎念几遍规则,有个2周就把它忘干净了 _!!!。

三、异或运算法则

  • 归零律:a^a=0
  • 恒等律:a^0=a
  • 交换律: a^b = b^a
  • 结合律:abc = a(bc) = (ab)c
  • 自反律:aba = b

java中异或运算符为 ^

四、异或加密原理

  • 异或自反律:aba = b

    看完异或运算法则之后就能明白,加解密用的是异或的自反律,这是一个神奇的性质。
  • 例如:不引入第三变量,交换两个数值?
public static void main(String[] args) {
    int a = 88;
    int b = 99;
    System.out.println(MessageFormat.format("交换前\ta={0}\tb={1}",a,b));
    a = a^b;
    b = a^b;
    a = a^b;
    System.out.println(MessageFormat.format("交换后\ta={0}\tb={1}",a,b));
}
输出:
交换前	a=88	b=99
交换后	a=99	b=88
  • 内容加密

    在异或自反律(aba = b)中,如果把a看做加密的盐值,b看做明文,使用盐值a对明文b连续执行两次“异或”操作即可得到原来的明文b内容。通过该定律我们就可以实现对二进制文件的简单加解密。
    系统中存在的物理文件,都是由很多个byte组成的,我们只需按位对物理文件进行读写加密就可以实现加解密。
    盐值的长短决定了密文的破解难易。
    比如可以按1位去异或,也可以按4位去异或,等等!

五、加密算法实现

  • 读取使用InputStream类
  • 写入使用RandomAccessFile类

    RandomAccessFile是Java输入/输出流体系中功能最丰富的文件内容访问类,它提供了众多的方法来访问文件内容,它既可以读取文件内容,也可以向文件输出数据。与普通的输入/输出流不同的是,RandomAccessFile支持"随机访问"的方式,程序可以直接跳转到文件的任意地方来读写数据。

刚开始使用的是OutputStream类写内容,发现调用write方法后,文件内容变小了_!!!

  • 代码实现
    public static void main(String[] args) throws Exception {
        //你好世界!hello,world!
        String fileName = "E:\\downloads\\text.txt";
        byte salt = 10;
        int readLength = 128; //读取长度
        byte[] cipherBytes = new byte[readLength];
        //读流
        try(InputStream fr = new FileInputStream(fileName)){
            byte[] buffer = new byte[readLength];
            fr.read(buffer,0,buffer.length);
            //按位执行异或
            for(int i=0;i

你可能感兴趣的:(java,开发语言)