1. 程式人生 > >JAVA加密解密之凱撒加密(Caesar cipher)演算法

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

凱撒加密演算法簡介

凱撒加密(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