维吉尼亚密码输出

3
我看了一下在http://rosettacode.org/wiki/Vigen%C3%A8re_cipher#Java提供的Vigene密码源代码。我试着测试了一下程序,但是输出的结果和我根据vigene期望的不一样。例如,当“dog”为单词,“bob”为密钥时,我期望它被加密为“ech”,但实际上却是“qot”。请帮我看看这个问题。
public static void main(String[] args) {
    String key = "bob";
    String ori = "dog";
    String enc = encrypt(ori, key);
    System.out.println(enc);

}

static String encrypt(String text, final String key) {
    String res = "";
    text = text.toLowerCase();
    for (int i = 0, j = 0; i < text.length(); i++) {
        char c = text.charAt(i);
        if (c < 'a' || c > 'z') continue;
        res += (char)((c + key.charAt(j) - 2 * 'A') % 26 + 'A');
        j = ++j % key.length();
    }
    return res;
}

然而输出结果有所不同。这是因为我对密码的理解有误,还是因为采用了与众所周知的维吉尼亚密码不同的方法?

然而输出是不同的,那它是什么呢? - Andy Turner
@RishavKundu 假设那不是我没听说过的缩写,最好在问题中包含它 - 已添加。 - Andy Turner
@AndyTurner请注意,输出是大写的;不过我不知道这是否很重要。 - xrisk
2个回答

0

因为您将文本设置为加密为小写,所以尝试将这些字符字面值也改为小写:

res += (char)((c + key.charAt(j) - 2 * 'a') % 26 + 'a');

当将int转换为char时,您必须考虑到'a'的整数值不等于'A'。因为您正在检查当前字符是否在'a'和'z'之间(因为您已将其设置为小写),所以您应该也要输出小写字母。


啊,谢谢!你能不能顺便解释一下这行代码实际上在做什么? - user2982832
因为Java中的字符值具有不同的整数值(2 * 'a'与2 * 'A'不同),所以根据计算出的整数值,转换为字符后得到的字符会略有不同。 - MrPublic

0

正如用户所指出的那样,您应该将该行更改为:

res += (char)((c + key.charAt(j) - 2 * 'a') % 26 + 'a');

或者,您可以更改这个:

if (c < 'a' || c > 'z') continue;

转换为:

if (c < 'A' || c > 'Z') continue;

确保在将ASCII转换回字母时,使用正确的ASCII值(即大写字母为65 (A),小写字母为97 (a))。


1
或者,您可以更改... 这意味着由于前几行中的 text.toLowerCase() ,什么都不会被加密。 - Andy Turner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接