Java实现Caesar cypher时for-each循环字符位移失效问题咨询
问题排查与解决方案
1. 为什么不能替换赋值语句
Java的for-each循环属于只读遍历,迭代变量c是从数组中拷贝出来的临时副本,不是指向数组元素的引用:
- 修改
c的值仅会改变这个临时变量的内容,不会回写到原charArray数组中,循环结束后数组仍然是加密前的原始内容,完全没有加密效果。 - 你原来的写法通过下标
j直接定位数组的对应位置赋值,才是真正修改了数组存储的内容。
2. 现有代码无法正常运行的原因
你的代码存在两个核心逻辑漏洞:
- 仅支持小写字母加密,大写字母会直接乱码:当前位移逻辑是基于小写字母起始值
'a'计算的,如果输入包含大写字母,c - 'a'的结果会超出0~25的正常范围,位移结果完全不符合预期。 - 未处理负位移场景:如果密钥
k是负数(常见于解密场景),c + k - (int)'a'的计算结果可能为负,Java的取模运算符%对负数计算的结果仍为负,加'a'后得到的字符不在小写字母范围内,输出乱码。
修正后的参考代码
for (int i = 3; i < args.length; i++) { // 遍历所有待加密的入参字符串 int k = Integer.parseInt(args[2]); // 预处理密钥,保证范围在0~25之间,同时兼容负密钥解密场景 k = (k % 26 + 26) % 26; char[] charArray = args[i].toCharArray(); int j = 0; for (char c : charArray) { if (Character.isLowerCase(c)) { // 小写字母基于'a'计算位移 charArray[j] = (char) ((c - 'a' + k) % 26 + 'a'); } else if (Character.isUpperCase(c)) { // 大写字母单独基于'A'计算位移 charArray[j] = (char) ((c - 'A' + k) % 26 + 'A'); } // 非字母字符不做处理,直接保留原值 j++; } System.out.println(charArray); }
内容的提问来源于stack exchange,提问作者GR33NTE4
相关产品推荐
相关产品推荐

