【问题标题】:Case sensitive Vigenere cipher produces wrong output区分大小写的 Vigenere 密码产生错误的输出
【发布时间】:2016-12-07 03:28:38
【问题描述】:

我付出了很多努力来使密码更加健壮,以便输出区分大小写。

意思是,如果消息字符串中有一个大写字母,则输出将在该位置的字符串中包含一个编码的大写字母。例如,InpUT MesSagE 变为HrhTS WwlReyD。使用的密钥是test

public String encrypt(String text, final String key) {
    int a_num = (int) 'a';
    int A_num = (int) 'A';
    String output = "";
    for (int i = 0, j = 0; i < text.length(); i++) {
        int cur = (int) text.charAt(i);
        // check for spaces
        if (text.charAt(i) == ' ') {
            output += " ";
        // check for lowercase
        } else if (cur >= 'a' && cur < 'z' + 26) {
            output += Character.toString((char) ((cur + key.charAt(j) - 2 * 'a') % 26 + 'a'));
            j = ++j % key.length();
        // check for uppercase between 'N' and 'Z'
        } else if (cur >= 'N' && cur < 'Z') {
            output += Character.toString((char) ((cur + key.charAt(j) - 2 * 'A') % 26 + 'N' + 7));
            j = ++j % key.length();
        // check for uppercase between 'A' and 'M'
        } else {
            output += Character.toString((char) ((cur + key.charAt(j) - 2 * 'A') % 26 + 'A' - 6));
            j = ++j % key.length();
        }
    }
    return output;
}

目前,所有小写字母似乎都正确,有些大写字母也正确。我的问题是有时大写是错误的,例如由于我不正确的数学/逻辑,符号将成为输出的一部分。

我很确定问题出在代码的这些部分中:

((cur + key.charAt(j) - 2 * 'A') % 26 + 'A' - 6));

【问题讨论】:

  • 您能否在edit 您的问题中包含key 用于将hOW Fun 转换为qZU Grv 或您正在使用的key 示例输入和输出?
  • 该消息和密钥的所需输出为BrhNM QwlLeyX
  • 带有 U 和 t(测试中的第四个字母) 85+116=201 201-130=81 81 mod 26=3 添加 N (78) 和 7 得到 88,即 X 而不是 T ?此外,正如所写的“Z”将进入最后的 else,如果它是你想要的,至少值得评论。
  • 'N'+7 已经是 'U。" 任何 6 或更多的余数都会带您超出字母表的末尾,进入您观察到的时髦字符。但这可能会发生(让我们说测试键有从 a 到 z 的任何位置,您可能会击中所有可能的余数 0 到 25。这也将解释为什么在您的最后一个子句中小于 6 的余数会在字母表开头之前占据字符。
  • 不明白为什么 A..M 和 N..Z 会是不同的情况。

标签: java encryption vigenere


【解决方案1】:
public String encrypt(String text, final String key) {
    // we assume the key is all lower case
    // and only inputs are letters and space (could enhance to leave all else alone)
    int a_num = (int) 'a'; //unused?
    int A_num = (int) 'A';//unused?
    String output = "";

    for (int i = 0, j = 0; i < text.length(); i++) {
        int cur = (int) text.charAt(i);

        // check for spaces
        if (text.charAt(i) == ' ') {
            output += " ";
        }
        // check for lowercase
        else if (cur >= 'a' && cur <= 'z') {
            output += Character.toString((char) ((cur + key.charAt(j) - 2 * 'a') % 26 + 'a'));
            j = ++j % key.length();
        }
        // should work for uppercase between 'A' and 'Z'
        else {
            output += Character.toString((char) ((cur -'A' + key.charAt(j) - 'a') % 26 + 'A'));
            j = ++j % key.length();
        }
    }
    return output;
}

【讨论】:

  • 我会尽快尝试。我假设要“增强”它以单独留下其他字符,它需要另一个捕获所有符号等的 else 语句,就像空格检查器一样?这是怎么做到的?
  • 我实际上似乎无法正确获取解密方法。几乎是一样的,我知道,但两条主线是我无法缩小范围的。
  • 处理其他字符我会删除第一个if,将当前的else设为if,将当前的else设为else if (cur>='A' && cur
  • 对于 unshifting,首先尝试使其适用于所有小写字母。我认为这看起来像 cur - key.charAt(j) 和 'a''s 取消,我相信。在大写的情况下,您仍然需要 (cur-'A'),但现在 + 'a'-key.charAt(j)。
  • 取消 a 是什么意思?按照您的建议,它看起来像这样:output += Character.toString((char) ((cur - key.charAt(j) - 2 * 'a') % 26 + 'a'));output += Character.toString((char) ((cur - 'A' - key.charAt(j) + 'a') % 26 + 'A'));
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多