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

    xiaoxiao2021-12-14  18

    凯撒加密算法简介

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

    凯撒加密算法实现

    package com.jianggujin.codec; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * 凯撒加密 * * @author jianggujin * */ public class JCaesar { /** * 加密 * * @param str * @param k * @return */ public static String encrypt(String str, int k) { StringBuilder result = new StringBuilder(); for (char c : str.toCharArray()) { result.append(encrypt(c, k)); } return result.toString(); } /** * 解密 * * @param str * @param k * @return */ public static String decrypt(String str, int k) { // 取相反数 k = 0 - k; return encrypt(str, k); } /** * 包裹输入流,原输入流为加密数据输入流 * * @param in * @param k * @return */ public static InputStream wrap(InputStream in, int k) { return new DecInputStream(in, k); } /** * 包裹输出流,包裹后的输出流为加密输出流 * * @param out * @param k * @return */ public static OutputStream wrap(OutputStream out, int k) { return new EncOutputStream(out, k); } /** * 加密输出流 * * @author jianggujin * */ private static class EncOutputStream extends OutputStream { private final OutputStream out; private final int k; EncOutputStream(OutputStream out, int k) { this.out = out; this.k = k; } @Override public void write(int b) throws IOException { out.write(encrypt((char) b, k)); } } /** * 解密输入流 * * @author jianggujin * */ private static class DecInputStream extends InputStream { private final InputStream in; private final int k; DecInputStream(InputStream in, int k) { this.in = in; this.k = 0 - k; } @Override public int read() throws IOException { int i = in.read(); if (i == -1) { return i; } return encrypt((char) i, k); } } /** * 加密 * * @param c * @param k * @return */ private static char encrypt(char c, int k) { // 如果字符串中的某个字符是小写字母 if (c >= 'a' && c <= 'z') { c += k % 26; // 移动key&位 if (c < 'a') { c += 26; // 向左超界 } else if (c > 'z') { c -= 26; // 向右超界 } } // 如果字符串中的某个字符是大写字母 else if (c >= 'A' && c <= 'Z') { c += k % 26; // 移动key&位 if (c < 'A') { c += 26;// 同上 } else if (c > 'Z') { c -= 26;// 同上 } } return c; } }

    测试代码:

    package com.jianggujin.codec.test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.junit.Test; import com.jianggujin.codec.JCaesar; public class CaesarTest { String str = "jianggujin"; File file = new File(getClass().getSimpleName() + ".dat"); int k = 10; @Test public void test() throws IOException { System.out.println("原串:" + str + ", 偏移:" + k); String encrypt = JCaesar.encrypt(str, k); System.out.println("加密:" + encrypt); System.out.println("解密:" + JCaesar.decrypt(encrypt, k)); System.out.print("输出流加密:" + file.getAbsolutePath()); OutputStream out = JCaesar.wrap(new FileOutputStream(file), k); out.write(str.getBytes()); out.flush(); System.out.println(); System.out.print("输入流解密:"); InputStream in = JCaesar.wrap(new FileInputStream(file), k); byte[] buffer = new byte[1024]; int len = in.read(buffer); System.out.println(new String(buffer, 0, len)); } }

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

    转载请注明原文地址: https://ju.6miu.com/read-971042.html

    最新回复(0)