Java 实现异或(xor)算法的加密和解密

左手的ㄟ右手 2021-09-22 22:18 563阅读 0赞

本文链接: https://blog.csdn.net/xietansheng/article/details/88420949

1. 异或(xor)加密原理

一个整数 a 和任意一个整数 b 异或两次,得到的结果是整数 a 本身,即: a == a ^ b ^ b

这里的 a 就是需要加密的原数据,b 则是密钥。a ^ b 就是加密过程,异或的结果就是加密后的密文。密文 (a ^ b) 再与密钥 b 异或,就是解密过程,得到的结果就是原数据 a 本身。

  1. a = 原数据
  2. b = 密钥
  3. // 一次异或, 加密得到密文
  4. c = a ^ b
  5. // 二次异或, 解密得到原数据(d == a)
  6. d = c ^ b

异或加密如果同时知道原文和密文,则对比原文和密文可以推算出密钥,因此异或加密安全性较低,一般只用于简单的加密。

2. 异或加密代码实例

2.1 异或加密工具类封装:XORUtils

XORUtils.java完整源码:

  1. package com.xiets.xor;
  2. import java.io.BufferedOutputStream;
  3. import java.io.Closeable;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.io.OutputStream;
  10. /** * 异或(xor)算法加密/解密工具 * * @author xietansheng */
  11. public class XORUtils {
  12. /** * 异或算法加密/解密 * * @param data 数据(密文/明文) * @param key 密钥 * @return 返回解密/加密后的数据 */
  13. public static byte[] encrypt(byte[] data, byte[] key) {
  14. if (data == null || data.length == 0 || key == null || key.length == 0) {
  15. return data;
  16. }
  17. byte[] result = new byte[data.length];
  18. // 使用密钥字节数组循环加密或解密
  19. for (int i = 0; i < data.length; i++) {
  20. // 数据与密钥异或, 再与循环变量的低8位异或(增加复杂度)
  21. result[i] = (byte) (data[i] ^ key[i % key.length] ^ (i & 0xFF));
  22. }
  23. return result;
  24. }
  25. /** * 对文件异或算法加密/解密 * * @param inFile 输入文件(密文/明文) * @param outFile 结果输出文件 * @param key 密钥 */
  26. public static void encryptFile(File inFile, File outFile, byte[] key) throws Exception {
  27. InputStream in = null;
  28. OutputStream out = null;
  29. try {
  30. // 文件输入流
  31. in = new FileInputStream(inFile);
  32. // 结果输出流, 异或运算时, 字节是一个一个读取和写入, 这里必须使用缓冲流包装,
  33. // 等缓冲到一定数量的字节(10240字节)后再写入磁盘(否则写磁盘次数太多, 速度会非常慢)
  34. out = new BufferedOutputStream(new FileOutputStream(outFile), 10240);
  35. int b = -1;
  36. long i = 0;
  37. // 每次循环读取文件的一个字节, 使用密钥字节数组循环加密或解密
  38. while ((b = in.read()) != -1) {
  39. // 数据与密钥异或, 再与循环变量的低8位异或(增加复杂度)
  40. b = (b ^ key[(int) (i % key.length)] ^ (int) (i & 0xFF));
  41. // 写入一个加密/解密后的字节
  42. out.write(b);
  43. // 循环变量递增
  44. i++;
  45. }
  46. out.flush();
  47. } finally {
  48. close(in);
  49. close(out);
  50. }
  51. }
  52. private static void close(Closeable c) {
  53. if (c != null) {
  54. try {
  55. c.close();
  56. } catch (IOException e) {
  57. // nothing
  58. }
  59. }
  60. }
  61. }

异或加密和解密用的方法都是同一个,XORUtils类中有两个公开静态方法:

  1. // 加密/解密 byte 数组数据
  2. static byte[] encrypt(byte[] data, byte[] key)
  3. // 加密/解密 文件
  4. static void encryptFile(File inFile, File outFile, byte[] key)

2.2 XORUtils 工具类的使用

  1. package com.xiets.xor;
  2. import java.io.File;
  3. /** * @author xietansheng */
  4. public class Main {
  5. public static void main(String[] args) throws Exception {
  6. String content = "Hello world!"; // 原文内容
  7. String key = "123456"; // XOR 加密/解密用的原始密码
  8. // 加密数据, 返回密文
  9. byte[] cipherBytes = XORUtils.encrypt(content.getBytes(), key.getBytes());
  10. // 解密数据, 返回明文
  11. byte[] plainBytes = XORUtils.encrypt(cipherBytes, key.getBytes());
  12. // 输出解密后的明文: "Hello world!"
  13. System.out.println(new String(plainBytes));
  14. /* * XOR 对文件的加密/解密 */
  15. // 将 文件demo.java 加密后输出到 文件demo.jpg_cipher
  16. XORUtils.encryptFile(new File("demo.jpg"), new File("demo.jpg_cipher"), key.getBytes());
  17. // 将 文件demo.jpg_cipher 解密输出到 文件demo.jpg_plain
  18. XORUtils.encryptFile(new File("demo.jpg_cipher"), new File("demo.jpg_plain"), key.getBytes());
  19. // 对比 原文件demo.jpg 和 解密得到的文件demo.jpg_plain 两者的 MD5 将会完全相同
  20. }
  21. }

发表评论

表情:
评论列表 (有 0 条评论,563人围观)

还没有评论,来说两句吧...

相关阅读

    相关 运算实现加密解密

    异或运算中,如果某个字符(或数值)x 与 一个数值m 进行异或运算得到y,则再用y 与 m 进行异或运算就可以还原为 x ,因此应用这个原理可以实现数据的加密解密功能

    相关 加密算法

    异或加密是一种很简单的加密算法,无论是原理还是操作性上,都不具备任何难度,所以,在做一些简单的加密时,被广为采用。 但因为很简答,破解起来也很容易,所以对于更加私密的信息,不