## 加密算法和密钥的理解(单表替换为例) ##
### 1. 个人理解 ###
加密算法:是对加密规则或算法的抽象总结或设计;</br>
密钥:对具体的规则的参数,密码算法因为这些密钥而变得具体。</br>
在密码算法中输入密钥,形成具体的加密算法。
### 2. 单表替换 ###
单表替换是对26个字母按照一张密码映射表映射到密文的过程。</br>
其中上述描述的过程就是单表替换的加密算法。</br>
其中具体的字母映射表就是密钥,单表替换的密钥有26!≈4E24种。
### 3. 单表查询工具包 ###
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 仅限输入大写字母的明文 * * @author 61423 * */ public class SingleTableReplacementUtils { /** * 产生一个随机的密钥 * * @return */ public static Map<Character, Character> getKey() { // 定义一个map存放随机产生的密钥 Map<Character, Character> map = new HashMap<Character, Character>(); // 定义一个容纳26个字符的数组 char[] c = new char[26]; // 将26个字母赋值给数组 for (int i = 0; i < c.length; i++) { c[i] = (char) ('A' + i); } // 定义一个list,当作栈 List<Character> list = new ArrayList<Character>(); for (int i = 0; i < c.length; i++) { list.add((char) ('A' + i)); } // 将密钥存放到map中,随机产生的密钥共有26! for (int i = 0; i < c.length; i++) { // 从当前的list中的子母中获取一个值的索引 int index = (int) Math.floor((Math.random() * (26 - i))); Character key = c[i]; Character value = list.get(index); list.remove(index); map.put(key, value); } return map; } /** * 反转密钥,便于解密 * * @param key * @return */ private static Map<Character, Character> reverseKey(Map<Character, Character> key) { Map<Character, Character> map = new HashMap<Character, Character>(); // 转换密钥映射关系,便于解析 for (Character c_key : key.keySet()) { map.put(key.get(c_key), c_key); } return map; } /** * 根据密钥对输入的字符进行加密 * * @param src * @param map * @return */ public static String getCiphertext(String plaintext, Map<Character, Character> key) { StringBuffer ciphertext = new StringBuffer(); char[] charArray = plaintext.toCharArray(); for (char c : charArray) { ciphertext.append(key.get(c)); } return ciphertext.toString(); } /** * 根据密钥对字符串解密 * * @param ciphertext * @param map * @return */ public static String getPlaintext(String ciphertext, Map<Character, Character> key) { StringBuffer plaintext = new StringBuffer(); char[] charArray = ciphertext.toCharArray(); Map<Character, Character> reverseKey = reverseKey(key); // 解析字符串 for (char c : charArray) { plaintext.append(reverseKey.get(c)); } return plaintext.toString(); } /** * 破解此算法 */ public static Boolean getHackString(String ciphertext, String username) { // 返回值 Boolean res = false; String hackString = ""; // 定义key组合,和value组合 char[] cs = new char[26]; for (int i = 0; i < cs.length; i++) { cs[i] = (char) ('A' + i); } List<Character> list = new ArrayList<Character>(); for (int i = 0; i < cs.length; i++) { list.add((char) ('A' + i)); } // 生成密钥并解密 Map<Character, Character> map = new HashMap<Character, Character>(); // 生成转存的list,开辟新的空间,避免引用同一个地址 List<Character> listb = new ArrayList<Character>(); List<Character> listc = new ArrayList<Character>(); List<Character> listd = new ArrayList<Character>(); List<Character> liste = new ArrayList<Character>(); List<Character> listf = new ArrayList<Character>(); List<Character> listg = new ArrayList<Character>(); List<Character> listh = new ArrayList<Character>(); List<Character> listi = new ArrayList<Character>(); List<Character> listj = new ArrayList<Character>(); List<Character> listk = new ArrayList<Character>(); List<Character> listl = new ArrayList<Character>(); List<Character> listm = new ArrayList<Character>(); List<Character> listn = new ArrayList<Character>(); List<Character> listo = new ArrayList<Character>(); List<Character> listp = new ArrayList<Character>(); List<Character> listq = new ArrayList<Character>(); List<Character> listr = new ArrayList<Character>(); List<Character> lists = new ArrayList<Character>(); List<Character> listt = new ArrayList<Character>(); List<Character> listu = new ArrayList<Character>(); List<Character> listv = new ArrayList<Character>(); List<Character> listw = new ArrayList<Character>(); List<Character> listx = new ArrayList<Character>(); List<Character> listy = new ArrayList<Character>(); List<Character> listz = new ArrayList<Character>(); int count = 0; // 计数密钥 Long oldTime = System.currentTimeMillis(); // 为了计算计算机的计算能力 for (int a = 0; a < list.size(); a++) { // 每层之间使用中间量记录状态 // 第一个字母的映射 Character key_a = cs[cs.length - list.size()]; Character value_a = list.get(a); // a 递增遍历list中的元素,不需要这时候去掉元素,还需要继续遍历 // list.remove(a); // 传递之前去掉就可以 map.put(key_a, value_a); // listb = list; // 保存list的状态,向下传递,此方式引用同一个地址取消 for (Character character : list) { listb.add(character); } listb.remove(a); // 向下传递之前,去掉已经使用的元素,初始化下一层的状态 for (int b = 0; b < listb.size(); b++) { Character key_b = cs[cs.length - listb.size()]; // 此时已经减少一个 Character value_b = listb.get(b); // listb.remove(b); map.put(key_b, value_b); //listc = listb; for (Character character : listb) { listc.add(character); } listc.remove(b); if(b == (listb.size()-1)) { listb.clear();; } for (int c = 0; c < listc.size(); c++) { Character key_c = cs[cs.length - listc.size()]; Character value_c = listc.get(c); // list.remove(c); // listd = listc; for (Character character : listc) { listd.add(character); } listd.remove(c); map.put(key_c, value_c); if(c == (listc.size()-1)) { listc.clear();; } for (int d = 0; d < listd.size(); d++) { Character key_d = cs[cs.length - listd.size()]; Character value_d = listd.get(d); // list.remove(d); // liste = listd; for (Character character : listd) { liste.add(character); } liste.remove(d); map.put(key_d, value_d); if(d == (listd.size()-1)) { listd.clear();; } for (int e = 0; e < liste.size(); e++) { Character key_e = cs[cs.length - liste.size()]; Character value_e = liste.get(e); // list.remove(e); // listf = liste; for (Character character : liste) { listf.add(character); } listf.remove(e); map.put(key_e, value_e); if(e == (liste.size()-1)) { liste.clear();; } for (int f = 0; f < listf.size(); f++) { Character key_f = cs[cs.length - listf.size()]; Character value_f = listf.get(f); // list.remove(f); // listg = listf; for (Character character : listf) { listg.add(character); } listg.remove(f); map.put(key_f, value_f); if(f == (listf.size()-1)) { listf.clear();; } for (int g = 0; g < listg.size(); g++) { Character key_g = cs[cs.length - listg.size()]; Character value_g = listg.get(g); // list.remove(g); // listh = listg; for (Character character : listg) { listh.add(character); } listh.remove(g); map.put(key_g, value_g); if(g == (listg.size()-1)) { listg.clear();; } for (int h = 0; h < listh.size(); h++) { Character key_h = cs[cs.length - listh.size()]; Character value_h = listh.get(h); // list.remove(h); // listi = listh; for (Character character : listh) { listi.add(character); } listi.remove(h); map.put(key_h, value_h); if(h == (listh.size()-1)) { listh.clear();; } for (int i = 0; i < listi.size(); i++) { Character key_i = cs[cs.length - listi.size()]; Character value_i = listi.get(i); // list.remove(i); // listj = listi; for (Character character : listi) { listj.add(character); } listj.remove(i); map.put(key_i, value_i); if(i == (listi.size()-1)) { listi.clear();; } for (int j = 0; j < listj.size(); j++) { Character key_j = cs[cs.length - listj.size()]; Character value_j = listj.get(j); // list.remove(j); // listk = listj; for (Character character : listj) { listk.add(character); } listk.remove(j); map.put(key_j, value_j); if(j == (listj.size()-1)) { listj.clear();; } for (int k = 0; k < listk.size(); k++) { Character key_k = cs[cs.length - listk.size()]; Character value_k = listk.get(k); // list.remove(k); // listl = listk; for (Character character : listk) { listl.add(character); } listl.remove(k); map.put(key_k, value_k); if(k == (listk.size()-1)) { listk.clear();; } for (int l = 0; l < listl.size(); l++) { Character key_l = cs[cs.length - listl.size()]; Character value_l = listl.get(l); // list.remove(l); // listm = listl; for (Character character : listl) { listm.add(character); } listm.remove(l); map.put(key_l, value_l); if(l == (listl.size()-1)) { listl.clear();; } for (int m = 0; m < listm.size(); m++) { Character key_m = cs[cs.length - listm.size()]; Character value_m = listm.get(m); // list.remove(m); // listn = listm; for (Character character : listm) { listn.add(character); } listn.remove(m); map.put(key_m, value_m); if(m == (listm.size()-1)) { listm.clear();; } for (int n = 0; n < listn.size(); n++) { Character key_n = cs[cs.length - listn.size()]; Character value_n = listn.get(n); // list.remove(n); // listo = listn; for (Character character : listn) { listo.add(character); } listo.remove(n); map.put(key_n, value_n); if(n == (listn.size()-1)) { listn.clear();; } for (int o = 0; o < listo.size(); o++) { Character key_o = cs[cs.length - listo.size()]; Character value_o = listo.get(o); // list.remove(o); // listp = listo; for (Character character : listo) { listp.add(character); } listp.remove(o); map.put(key_o, value_o); if(o == (listo.size()-1)) { listo.clear();; } for (int p = 0; p < listp.size(); p++) { Character key_p = cs[cs.length - listp.size()]; Character value_p = listp.get(p); // list.remove(p); // listq = listp; for (Character character : listp) { listq.add(character); } listq.remove(p); map.put(key_p, value_p); if(p == (listp.size()-1)) { listp.clear();; } for (int q = 0; q < listq.size(); q++) { Character key_q = cs[cs.length - listq.size()]; Character value_q = listq.get(q); // list.remove(q); // listr = listq; for (Character character : listq) { listr.add(character); } listr.remove(q); map.put(key_q, value_q); for (int r = 0; r < listr.size(); r++) { Character key_r = cs[cs.length - listr.size()]; Character value_r = listr.get(r); // list.remove(r); // lists = listr; for (Character character : listr) { lists.add(character); } lists.remove(r); map.put(key_r, value_r); for (int s = 0; s < lists.size(); s++) { Character key_s = cs[cs.length - lists.size()]; Character value_s = lists.get(s); // list.remove(s); // listt = lists; for (Character character : lists) { listt.add(character); } listt.remove(s); map.put(key_s, value_s); for (int t = 0; t < listt .size(); t++) { Character key_t = cs[cs.length - listt.size()]; Character value_t = listt.get(d); // list.remove(t); // listu = listt; for (Character character : listt) { listu.add(character); } listu.remove(t); map.put(key_t, value_t); for (int u = 0; u < listu .size(); u++) { Character key_u = cs[cs.length - listu.size()]; Character value_u = listu .get(u); // list.remove(u); // listv = listu; for (Character character : listu) { listv.add(character); } listv.remove(u); map.put(key_u, value_u); for (int v = 0; v < listv .size(); v++) { Character key_v = cs[cs.length - listv.size()]; Character value_v = listv .get(v); // list.remove(v); // listw = listv; for (Character character : listv) { listw.add(character); } listw.remove(v); map.put(key_v, value_v); for (int w = 0; w < listw .size(); w++) { Character key_w = cs[cs.length - listw.size()]; Character value_w = listw .get(w); // list.remove(w); // listx = listw; for (Character character : listw) { listx.add(character); } listx.remove(w); map.put(key_w, value_w); for (int x = 0; x < listx .size(); x++) { Character key_x = cs[cs.length - listx.size()]; Character value_x = listx .get(x); // list.remove(x); // listy = listx; for (Character character : listx) { listy.add(character); } listy.remove(x); map.put(key_x, value_x); for (int y = 0; y < listy .size(); y++) { Character key_y = cs[cs.length - listy.size()]; Character value_y = listy .get(y); // list.remove(y); // listz = listy; for (Character character : listy) { listz.add(character); } listz.remove(y); map.put(key_y, value_y); for (int z = 0; z < listz .size(); z++) { Character key_z = cs[cs.length - listz.size()]; Character value_z = listz .get(z); //list.remove(z); map.put(key_z, value_z); System.out .println(++count+" "+map); // 运行1秒停止 if(System.currentTimeMillis()-oldTime>=1000L) { System.out .println(count); System.exit(0); } hackString = getPlaintext( ciphertext, map); if (hackString .equals(username)) { res = true; return res; } if(z == (listz.size()-1)) { listz.clear();; map.remove(key_z); } } if(y == (listy.size()-1)) { listy.clear();; map.remove(key_y); } } if(x == (listx.size()-1)) { listx.clear();; map.remove(key_x); } } if(w == (listw.size()-1)) { listw.clear();; map.remove(key_w); } } if(v == (listv.size()-1)) { listv.clear();; map.remove(key_v); } } if(u == (listu.size()-1)) { listu.clear();; map.remove(key_u); } } if(t == (listt.size()-1)) { listt.clear();; map.remove(key_t); } } if(s == (lists.size()-1)) { lists.clear();; map.remove(key_s); } } if(r == (listr.size()-1)) { listr.clear();; map.remove(key_r); } } if(q == (listq.size()-1)) { listq.clear();; map.remove(key_q); } } if(p == (listp.size()-1)) { listp.clear();; map.remove(key_p); } } if(o == (listo.size()-1)) { listo.clear();; map.remove(key_o); } } if(n == (listn.size()-1)) { listn.clear();; map.remove(key_n); } } if(m == (listm.size()-1)) { listm.clear();; map.remove(key_m); } } if(l == (listl.size()-1)) { listl.clear();; map.remove(key_l); } } if(k == (listk.size()-1)) { listk.clear();; map.remove(key_k); } } if(j == (listj.size()-1)) { listj.clear();; map.remove(key_j); } } if(i == (listi.size()-1)) { listi.clear();; map.remove(key_i); } } if(h == (listh.size()-1)) { listh.clear();; map.remove(key_h); } } if(g == (listg.size()-1)) { listg.clear();; map.remove(key_g); } } if(f == (listf.size()-1)) { listf.clear();; map.remove(key_f); } } if(e == (liste.size()-1)) { liste.clear();; map.remove(key_e); } } if(d == (listd.size()-1)) { listd.clear();; map.remove(key_d); } } if(c == (listc.size()-1)) { listc.clear();; map.remove(key_c); } } if(b == (listb.size()-1)) { listb.clear();; map.remove(key_b); } } } return res; } }