Kotlin版Vigenère解码异常,Python版本正常,求排查解决
Kotlin Vigenère解码错误排查与修复
问题根源
Python与Kotlin的取模运算行为差异是导致解码错误的核心原因:
- Python中,
负数 % 26会返回非负余数(例如-1 % 26 = 25),确保计算结果始终落在字母的ASCII范围内。 - Kotlin中,
负数 % 26会保留负号(例如-1 % 26 = -1),直接加上65/97后会生成非字母的ASCII字符,最终导致解码结果错乱。
修复方案
调整Kotlin代码中的取模逻辑,确保余数始终为非负数,以下两种方式均可实现:
方式1:使用Math.floorMod函数(推荐)
Math.floorMod的行为与Python的%完全一致,会返回非负余数:
fun decodeVigenere(message: String): String { val key = "SecureKey" val decodedMessage = StringBuilder() var i = 0 for (char in message) { if (char.isLetter()) { val keyChar = if (char.isUpperCase()) { key.uppercase()[i % key.length] } else { key.lowercase()[i % key.length] } val offset = if (char.isUpperCase()) 65 else 97 val decodedCode = Math.floorMod(char.code - keyChar.code, 26) + offset decodedMessage.append(decodedCode.toChar()) i += 1 } else { decodedMessage.append(char) } } return decodedMessage.toString() }
方式2:手动修正负数余数
如果不想依赖Math.floorMod,可以通过先加26再取模的方式强制余数非负:
fun decodeVigenere(message: String): String { val key = "SecureKey" val decodedMessage = StringBuilder() var i = 0 for (char in message) { if (char.isLetter()) { if (char.isUpperCase()) { val diff = char.code - key.uppercase()[i % key.length].code val modResult = (diff % 26 + 26) % 26 // 确保余数非负 decodedMessage.append((modResult + 65).toChar()) } else { val diff = char.code - key.lowercase()[i % key.length].code val modResult = (diff % 26 + 26) % 26 // 确保余数非负 decodedMessage.append((modResult + 97).toChar()) } i += 1 } else { decodedMessage.append(char) } } return decodedMessage.toString() }
逻辑验证
以加密字符A、密钥字符Z(大写)为例:
- Python计算:
(65 - 90) %26 +65 = (-25)%26 +65 = 1+65=66(对应正确字符B) - 修复前Kotlin计算:
(65-90)%26 +65 = -25+65=40(对应非字母() - 修复后Kotlin计算:
Math.floorMod(-25,26)+65=1+65=66(正确得到B)
修改后Kotlin的解码结果将与Python、CyberChef完全一致。
内容的提问来源于stack exchange,提问作者Liam K.
相关产品推荐
相关产品推荐

