import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
/**
* “恺撒密码”据传是古罗马恺撒大帝用来保护重要军情的加密系统。
* 它是一种替代密码,通过将字母按顺序推后起3位起到加密作用,如将字母A换作字母D,
* 将字母B换作字母E。恺撒移位,将字母按顺序推后起3位起也可以换成19位,
* 就产生这样一个明密对照表, 因此,这里我们设移位为n,可以根据用户自定义移位数。
* 明:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
* 密:T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
* 明文 F O R E S T
* 密文 Y H K X L M
*/
public class KaiSaJaiMi {
/**
* 加密
*
* @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);
}
/**
* 加密输出流
*
*/
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));
}
}
/**
* 解密输入流
*
*/
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;
}
/**
* 数字映射字符串
* @param n
* @param m 对应0123456789
* @return
*/
private static String num2Str(String n,String m){
if(n.length()==0 || m.length()==0){
return "";
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < n.length(); i++) {
for (int j = 0; j < 10; j++) {
if(Integer.parseInt(String.valueOf(n.charAt(i))) == j){
result.append(m.charAt(j));
}
}
}
return result.toString();
}
/**
* 字符串映射数字
* @param n
* @param m 对应0123456789
* @return
*/
private static String str2Num(String n,String m){
if(n.length()==0 || m.length()==0){
return "";
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < n.length(); i++) {
for (int j = 0; j < 10; j++) {
if(String.valueOf(n.charAt(i)).equals(String.valueOf(m.charAt(j)))){
result.append(String.valueOf(j));
}
}
}
return result.toString();
}
public static void main(String[] args) {
String yuanStr = "368920";
String yingStr= "wErtoVseGk";
int k = 3;
String reString = num2Str(yuanStr,yingStr);
System.out.println("原串:" + yuanStr + ", 映射转换后:" + reString);
System.out.println("原串:" + reString + ", 偏移:" + k);
String encrypt = KaiSaJaiMi.encrypt(reString, k);
System.out.println("加密:" + encrypt);
System.out.println("解密:" + KaiSaJaiMi.decrypt(encrypt, k));
System.out.println("映射转换后:" + str2Num(reString, yingStr));
// File file = new File("test.dat");
// System.out.print("输出流加密:" + file.getAbsolutePath());
// OutputStream out = KaiSaJaiMi.wrap(new FileOutputStream(file), k);
// out.write(str.getBytes());
// out.flush();
// System.out.println();
// System.out.print("输入流解密:");
// InputStream in = KaiSaJaiMi.wrap(new FileInputStream(file), k);
// byte[] buffer = new byte[1024];
// int len = in.read(buffer);
// System.out.println(new String(buffer, 0, len));
}
}