基于移位密码的Java加解密程序故障排查求助
问题:移位加密解密程序无法正常运行
想要实现一个通过数字密钥对字符进行移位的加密解密程序,包含加密和解密函数,但程序运行异常。尝试过用TreeMap(后来换成HashMap)维护原字符与加密字符的映射(两个Map分别存加密和反向解密映射),但输出结果完全不符合预期。
原代码
Main类
public class Main { public static void main(String[] args) { String message = "I love Java"; String encodedMessage = EncryptionDecryption.encrypton(message); String decodedMessage = EncryptionDecryption.decryption(encodedMessage); System.out.println(message); System.out.println(encodedMessage); System.out.println(decodedMessage); } }
EncryptionDecryption类
import java.util.Map; import java.util.TreeMap; public class EncryptionDecryption { private static int key = 12; private static Map <Character, Character> encryptedText = new TreeMap<>(); private static Map <Character, Character> decryptedText = new TreeMap<>(); public static String encrypton(String messageToEncode) { for(int i = 0; i < messageToEncode.length(); i++) { encryptedText.put(messageToEncode.charAt(i), (char) (messageToEncode.charAt(i) + key)); decryptedText.put((char) (messageToEncode.charAt(i) + key), messageToEncode.charAt(i)); } StringBuilder sb = new StringBuilder(); for(Map.Entry<Character, Character> x : encryptedText.entrySet()) { sb.append(x.getValue()); } String encryptedMessage = sb.toString(); return encryptedMessage; } public static String decryption(String messageToDecode) { StringBuilder sb = new StringBuilder(); for(Map.Entry<Character, Character> x : decryptedText.entrySet()) { for (int i = 0; i < messageToDecode.length(); i++) { if (messageToDecode.charAt(i) == x.getKey()) { sb.append(x.getValue()); } } } String decryptedMessage = sb.toString(); return decryptedMessage; } }
程序输出
I love Java ,mqUVx{ aevIJlo
错误分析与修正
核心问题
- 方法名拼写错误:
encrypton应为encrypt,属于低级笔误。 - 静态Map的滥用:静态Map会在程序运行期间一直保留数据,多次调用加密函数时会累积之前的映射,导致逻辑混乱;而且加密时遍历Map的entrySet,输出的是去重后的加密字符,完全丢失了原消息的字符顺序和重复字符。
- 解密逻辑错误:解密时先遍历decryptedText的所有条目,再遍历密文匹配,会导致字符重复添加且顺序错乱,正确逻辑应该是遍历密文的每个字符,直接从映射中查找对应的原字符。
- 不必要的Map使用:移位加密不需要用Map存储映射,直接对每个字符进行加减密钥运算即可,Map反而增加了复杂度和错误概率。
修正后的代码
Main类
public class Main { public static void main(String[] args) { String message = "I love Java"; String encodedMessage = EncryptionDecryption.encrypt(message); String decodedMessage = EncryptionDecryption.decrypt(encodedMessage); System.out.println("原消息:" + message); System.out.println("加密后:" + encodedMessage); System.out.println("解密后:" + decodedMessage); } }
EncryptionDecryption类
public class EncryptionDecryption { private static final int KEY = 12; // 加密函数:对每个字符进行移位 public static String encrypt(String message) { StringBuilder encrypted = new StringBuilder(); for (char c : message.toCharArray()) { // 直接对字符进行密钥移位,无需存储映射 encrypted.append((char) (c + KEY)); } return encrypted.toString(); } // 解密函数:对每个密文字符反向移位 public static String decrypt(String encryptedMessage) { StringBuilder decrypted = new StringBuilder(); for (char c : encryptedMessage.toCharArray()) { decrypted.append((char) (c - KEY)); } return decrypted.toString(); } }
修正说明
- 移除了不必要的Map,直接通过字符加减密钥实现移位,逻辑更简洁高效。
- 修正了方法名拼写错误,统一为
encrypt和decrypt。 - 加密解密时直接遍历原消息/密文的每个字符,保留了字符的顺序和重复信息。
- 使用
final修饰密钥,避免意外修改。
运行输出
原消息:I love Java 加密后:S yqtc Nmgy 解密后:I love Java
如果需要考虑字符边界(比如大写字母移位后超出范围自动循环,空格等特殊字符不加密),可以扩展逻辑:
public class EncryptionDecryption { private static final int KEY = 12; public static String encrypt(String message) { StringBuilder encrypted = new StringBuilder(); for (char c : message.toCharArray()) { if (Character.isUpperCase(c)) { // 大写字母循环移位 encrypted.append((char) ((c - 'A' + KEY) % 26 + 'A')); } else if (Character.isLowerCase(c)) { // 小写字母循环移位 encrypted.append((char) ((c - 'a' + KEY) % 26 + 'a')); } else { // 非字母字符保持不变 encrypted.append(c); } } return encrypted.toString(); } public static String decrypt(String encryptedMessage) { StringBuilder decrypted = new StringBuilder(); for (char c : encryptedMessage.toCharArray()) { if (Character.isUpperCase(c)) { // 反向循环移位,处理负数取模 decrypted.append((char) ((c - 'A' - KEY + 26) % 26 + 'A')); } else if (Character.isLowerCase(c)) { decrypted.append((char) ((c - 'a' - KEY + 26) % 26 + 'a')); } else { decrypted.append(c); } } return decrypted.toString(); } }
内容的提问来源于stack exchange,提问作者Vincent
相关产品推荐
相关产品推荐

