多表密码实现报错求助:如何用两个密钥交替替换字符串字符?
多表密码实现问题修复
错误原因分析
你遇到的StringIndexOutOfBoundsException由以下逻辑错误导致:
- 字符串索引越界:原代码中
PT.charAt(pos)的pos是字符在小写字母表alpha中的索引(比如'H'转小写后是第7位),但PT长度仅为5,用pos作为PT的索引必然超出范围。 - String不可变性误解:Java中
String是不可变对象,PT.replace()不会修改原字符串,而是返回新字符串,原代码未接收返回值,等于没有执行任何替换操作。 - 循环变量混乱:循环体中手动执行
i++导致循环变量跳步,且一次处理两个字符的逻辑会忽略边界情况(比如明文长度为奇数时,最后一个字符会被错误处理)。 - 大小写不匹配:示例明文
Hello包含大写字母,但alpha是小写字母表,alpha.indexOf(PT.charAt(i))对大写字母会返回-1,引发后续错误。
修复后的代码
public class PolyalphabeticCipher { public static String encrypt(String plaintext, String k1, String k2) { String alpha = "abcdefghijklmnopqrstuvwxyz"; StringBuilder ciphertext = new StringBuilder(); for (int i = 0; i < plaintext.length(); i++) { char currentChar = plaintext.charAt(i); char lowerChar = Character.toLowerCase(currentChar); int pos = alpha.indexOf(lowerChar); // 处理非字母字符(可根据需求调整) if (pos == -1) { ciphertext.append(currentChar); continue; } // 交替选择密钥:第1个字符(i=0)用k1,第2个(i=1)用k2,以此类推 char encryptedChar = i % 2 == 0 ? k1.charAt(pos) : k2.charAt(pos); // 保留原字符的大小写 if (Character.isUpperCase(currentChar)) { encryptedChar = Character.toUpperCase(encryptedChar); } ciphertext.append(encryptedChar); } return ciphertext.toString(); } public static void main(String[] args) { String k1 = "asdfghjklzxcvbnmqwertyuiop"; String k2 = "qwertyuiopasdfghjklzxcvbnm"; String plaintext = "Hello"; String ciphertext = encrypt(plaintext, k1, k2); System.out.println(ciphertext); // 输出 ktcsn } }
关键修复点
- 用
StringBuilder高效构建密文,规避String不可变性带来的问题。 - 统一处理大小写,确保
alpha.indexOf()能正确定位字符,同时保留原明文的大小写格式。 - 根据循环索引的奇偶性交替选择密钥,逻辑清晰且覆盖所有字符(包括奇数长度的明文)。
- 增加非字母字符的处理逻辑,避免遇到非字母时程序报错。
内容的提问来源于stack exchange,提问作者Nora
相关产品推荐
相关产品推荐

