文章16 | 阅读 7024 | 点赞0
凯撒加密(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%26位
if (c < 'a') {
c += 26; // 向左超界
} else if (c > 'z') {
c -= 26; // 向右超界
}
}
// 如果字符串中的某个字符是大写字母
else if (c >= 'A' && c <= 'Z') {
c += k % 26; // 移动key%26位
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://blog.csdn.net/jianggujin/article/details/53447099
内容来源于网络,如有侵权,请联系作者删除!