网络加密算法之置换与替代算法
2021/5/15 22:25:36
本文主要是介绍网络加密算法之置换与替代算法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
主程序
/** * 程序控制台 * @author 落霞不孤 */ public class Main { private static Scanner in = new Scanner(System.in); public static void main(String[] args) { while (true) { System.out.println("实现的密码算法"); System.out.println("\t1.替代算法"); System.out.println("\t2.置换算法"); System.out.println("\t3.退出"); System.out.print("请输入需要的密码算法:"); int choice = in.nextInt(); switch (choice) { case 1: chooseFun(new SubstitutePassword()); break; case 2: chooseFun(new ReplacementPassword()); break; case 3: in.close(); return; default: System.out.println("选择有误~请重新输入..."); } } } private static void chooseFun(AbstractPassword abstractPassword) { System.out.println("密码算法功能:"); System.out.println("\t1.加密"); System.out.println("\t2.解密"); System.out.print("请输入需要的密码算法功能:"); int fun = in.nextInt(); if (fun == 1) { System.out.print("请输入明文:"); in.nextLine(); String plaintext = in.nextLine(); System.out.println("明文加密后的密文:" + abstractPassword.encryption(plaintext)); } if (fun == 2) { System.out.print("请输入密文:"); in.nextLine(); String ciphertext = in.nextLine(); System.out.println("密文解密后的明文:" + abstractPassword.decryption(ciphertext)); } } }
密码加密解密接口
/** * 加密解密接口 * @author 落霞不孤 */ public interface FindPassword { /** * 加密 * @param plaintext 明文 * @return 加密后的密文 */ String encryption(String plaintext); /** * 解密 * @param ciphertext 密文 * @return 解密后的明文 */ String decryption(String ciphertext); }
密码加密解密抽象类
/** * 抽象类密码 * @author 落霞不孤 */ public abstract class AbstractPassword implements FindPassword { public static String key; public static int k; /** * 输入密钥 k */ void inputK() { Scanner in = new Scanner(System.in); System.out.print("请输入密钥k:"); k = in.nextInt(); } /** * 输入密钥 key */ void inputKey() { Scanner in = new Scanner(System.in); System.out.print("请输入密钥key:"); key = in.nextLine(); } /** * 找出字母的位置,从0算起 * * @param c 字母 * @return 字母在字母表的位置 */ int posInAlphabet(char c) { int pos = Character.toLowerCase(c) - 97; return pos; } /** * 找出c偏移量为k的字母 * * @param c 字母 * @param k 偏移量 * @return c偏移量为k的字母 */ char findAlphabetByPos(char c, int k) { if (Character.isLowerCase(c)) { return (char) ((posInAlphabet(c) + k) % 26 + 97); } return (char) (char) ((posInAlphabet(c) + k) % 26 + 65); } /** * 获得密钥中每个字母出现的顺序 * * @param cipher 密钥 * @return map<Character, Integer> k 是字母,v是出现的顺序 */ public Map<Character, Integer> findCipherPos(String cipher) { Map<Character, Integer> map = new HashMap<Character, Integer>(); int weight = 0; char min; // 每次找出cipher的最小字符,并赋权重 while (cipher.length() > 0) { for (int i = 0; i < cipher.length(); i++) { min = cipher.charAt(i); for (int j = i + 1; j < cipher.length(); j++) { if (Character.toUpperCase(min) > Character.toUpperCase(cipher.charAt(j))) { min = cipher.charAt(j); } } // 找出最小的字母后,用""取代 cipher = cipher.replace(Character.toString(min), ""); map.put(min, weight++); break; } } return map; } /** * 将明文变成二维数组 * @param plaintext 明文 * @return 明文的二维数组 */ public char[][] getCipherTextArr(String plaintext) { // 去除明文空格 plaintext = plaintext.replace(" ", ""); int col = key.length(); int row = (int) Math.ceil(plaintext.length()*1.0 / col); // 存储明文的二维数组 char[][] plainArr = new char[row][col]; // 存储密文的二维数组 char[][] chars; // 把明文存入明文的二维数组,用空格填充不存在的元素 for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (i * col + j >= plaintext.length()) { plainArr[i][j] = ' '; } else { plainArr[i][j] = plaintext.charAt(i * col + j); } } } chars = rule(plainArr); return chars; } /** * 获取按照密钥字母顺序加密或者解密的二维数组 * @param text 密文或明文的二维数组 * @return 加密或者解密的二维数组 */ private char[][] rule(char[][] text) { char[][] chars = new char[text.length][text[0].length]; Map<Character, Integer> map = findCipherPos(key); // 加密或解密 int j = 0; for (char tmp : key.toCharArray()) { int pos = map.get(tmp); for (int i = 0; i < text.length; i++) { chars[i][j] = text[i][pos]; } j++; } return chars; } /** * 按照约定打印密文数组 * @param chars 密文数组 * @return 密文 */ public String getCipherTextArrStr(char[][] chars) { StringBuilder sb = new StringBuilder(); Map<Character, Integer> cipherPos = findCipherPos(key); for (char tmp : key.toCharArray()) { int pos = cipherPos.get(tmp); for (int i = 0; i < chars.length; i++) { if(chars[i][pos] != ' ') { sb.append(chars[i][pos]); } } } return sb.toString(); } /** * 将密文变成二维数组 * @param cipherText 密文 * @return 密文的二维数组 */ public char[][] getPlainTextArr(String cipherText) { // 去除密文空格 cipherText = cipherText.replace(" ", ""); int col = key.length(); int row = (int) Math.ceil(cipherText.length()*1.0 / col); // 存储密文的二维数组 char[][] plainArr = new char[row][col]; // 把密文存入二维数组 // 不是填满矩阵 boolean flag = col * row > cipherText.length(); for (int i = 0; i < row; i++) { // 统计列数 int count = 0; for (int j = i; j <= cipherText.length(); j+=row) { // 填充空格 if (i * col + count >= cipherText.length()) { plainArr[i][count] = ' '; } else if(flag) { if (count > 1) { j--; } if (j == cipherText.length()) { j = cipherText.length() - 1; } if (j >= cipherText.length()) { j -= row; } plainArr[i][count] = cipherText.charAt(j); } else { if (j == cipherText.length()) { break; } plainArr[i][count] = cipherText.charAt(j); } count++; } } return plainArr; } /** * 将密文的二维数组解密,返回明文 * @param cipherArr 密文的二维数组解密 * @return 明文 */ public String getPlainTextArrStr(char[][] cipherArr) { StringBuilder sb = new StringBuilder(); char[][] tmp = rule(cipherArr); char[][] plainArr = rule(tmp); for (char[] chars : plainArr) { for (int j = 0; j < plainArr[0].length; j++) { if (chars[j] != ' ') { sb.append(chars[j]); } } } return sb.toString(); } }
置换算法具体实现
/** * 置换密码 * @author 落霞不孤 */ public class ReplacementPassword extends AbstractPassword{ @Override public String encryption(String plaintext) { inputKey(); char[][] cipherTextArr = getCipherTextArr(plaintext); return getCipherTextArrStr(cipherTextArr); } @Override public String decryption(String ciphertext) { inputKey(); char[][] cipherTextArr = getPlainTextArr(ciphertext); return getPlainTextArrStr(cipherTextArr); } }
替代算法
/** * 替代算法 * @author 落霞不孤 */ public class SubstitutePassword extends AbstractPassword{ @Override public String encryption(String plaintext) { inputK(); char[] chars = plaintext.toCharArray(); StringBuilder sb = new StringBuilder(); for (char ch : chars) { if (Character.isLetter(ch)) { char e = findAlphabetByPos(ch, k); sb.append(e); } else { sb.append(ch); } } return sb.toString(); } @Override public String decryption(String ciphertext) { inputK(); char[] chars = ciphertext.toCharArray(); StringBuilder sb = new StringBuilder(); for (char ch : chars) { if (Character.isLetter(ch)) { if (posInAlphabet(ch) < k) { // 找出密文字母在字母表位置,例如a,字母表位置为1,密钥假设k=2 // 计算出 newPos = 1 是需要倒退的距离,从z开始倒退 // 即可得到明文应该是y int newPos = posInAlphabet(ch) + 1 - k; if (Character.isLowerCase(ch)) { sb.append(findAlphabetByPos('z', newPos)); } else { sb.append(findAlphabetByPos('Z', newPos)); } } else { sb.append(findAlphabetByPos(ch, -k)); } } else { sb.append(ch); } } return sb.toString(); } }
这篇关于网络加密算法之置换与替代算法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南