JAVA加密解密之凯撒加密(Caesar cipher)算法

x33g5p2x  于2021-12-25 转载在 其他  
字(2.9k)|赞(0)|评价(0)|浏览(590)

凯撒加密算法简介

凯撒加密(Caesar cipher)是一种简单的消息编码方式:它根据字母表将消息中的每个字母移动常量位k。举个例子如果k等于3,则在编码后的消息中,每个字母都会向前移动3位:a会被替换为d;b会被替换成e;依此类推。字母表末尾将回卷到字母表开头。于是,w会被替换为z,x会被替换为a。

凯撒加密算法实现

  1. package com.jianggujin.codec;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. /** * 凯撒加密 * * @author jianggujin * */
  6. public class JCaesar {
  7. /** * 加密 * * @param str * @param k * @return */
  8. public static String encrypt(String str, int k) {
  9. StringBuilder result = new StringBuilder();
  10. for (char c : str.toCharArray()) {
  11. result.append(encrypt(c, k));
  12. }
  13. return result.toString();
  14. }
  15. /** * 解密 * * @param str * @param k * @return */
  16. public static String decrypt(String str, int k) {
  17. // 取相反数
  18. k = 0 - k;
  19. return encrypt(str, k);
  20. }
  21. /** * 包裹输入流,原输入流为加密数据输入流 * * @param in * @param k * @return */
  22. public static InputStream wrap(InputStream in, int k) {
  23. return new DecInputStream(in, k);
  24. }
  25. /** * 包裹输出流,包裹后的输出流为加密输出流 * * @param out * @param k * @return */
  26. public static OutputStream wrap(OutputStream out, int k) {
  27. return new EncOutputStream(out, k);
  28. }
  29. /** * 加密输出流 * * @author jianggujin * */
  30. private static class EncOutputStream extends OutputStream {
  31. private final OutputStream out;
  32. private final int k;
  33. EncOutputStream(OutputStream out, int k) {
  34. this.out = out;
  35. this.k = k;
  36. }
  37. @Override
  38. public void write(int b) throws IOException {
  39. out.write(encrypt((char) b, k));
  40. }
  41. }
  42. /** * 解密输入流 * * @author jianggujin * */
  43. private static class DecInputStream extends InputStream {
  44. private final InputStream in;
  45. private final int k;
  46. DecInputStream(InputStream in, int k) {
  47. this.in = in;
  48. this.k = 0 - k;
  49. }
  50. @Override
  51. public int read() throws IOException {
  52. int i = in.read();
  53. if (i == -1) {
  54. return i;
  55. }
  56. return encrypt((char) i, k);
  57. }
  58. }
  59. /** * 加密 * * @param c * @param k * @return */
  60. private static char encrypt(char c, int k) {
  61. // 如果字符串中的某个字符是小写字母
  62. if (c >= 'a' && c <= 'z') {
  63. c += k % 26; // 移动key%26位
  64. if (c < 'a') {
  65. c += 26; // 向左超界
  66. } else if (c > 'z') {
  67. c -= 26; // 向右超界
  68. }
  69. }
  70. // 如果字符串中的某个字符是大写字母
  71. else if (c >= 'A' && c <= 'Z') {
  72. c += k % 26; // 移动key%26位
  73. if (c < 'A') {
  74. c += 26;// 同上
  75. } else if (c > 'Z') {
  76. c -= 26;// 同上
  77. }
  78. }
  79. return c;
  80. }
  81. }

测试代码:

  1. package com.jianggujin.codec.test;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.OutputStream;
  8. import org.junit.Test;
  9. import com.jianggujin.codec.JCaesar;
  10. public class CaesarTest {
  11. String str = "jianggujin";
  12. File file = new File(getClass().getSimpleName() + ".dat");
  13. int k = 10;
  14. @Test
  15. public void test() throws IOException {
  16. System.out.println("原串:" + str + ", 偏移:" + k);
  17. String encrypt = JCaesar.encrypt(str, k);
  18. System.out.println("加密:" + encrypt);
  19. System.out.println("解密:" + JCaesar.decrypt(encrypt, k));
  20. System.out.print("输出流加密:" + file.getAbsolutePath());
  21. OutputStream out = JCaesar.wrap(new FileOutputStream(file), k);
  22. out.write(str.getBytes());
  23. out.flush();
  24. System.out.println();
  25. System.out.print("输入流解密:");
  26. InputStream in = JCaesar.wrap(new FileInputStream(file), k);
  27. byte[] buffer = new byte[1024];
  28. int len = in.read(buffer);
  29. System.out.println(new String(buffer, 0, len));
  30. }
  31. }

测试结果:
原串:jianggujin, 偏移:10
加密:tskxqqetsx
解密:jianggujin
输出流加密:F:\workspace\java\eclipse\JCodec\CaesarTest.dat
输入流解密:jianggujin

相关文章