【问题标题】:Caesar Cipher C# windows from, not decrypting only encryptingCaesar Cipher C# windows 来自,不解密只加密
【发布时间】:2021-12-29 09:47:48
【问题描述】:

当我尝试解密消息时,输出不是应该的。可能是解码代码的问题吗?问题是当您将移位高于 5 时会出现解码错误

加密:

Hello world

键: 20

输出: Byffi qilfx

解密:

Byffi qilfx

键: 20

输出.eRRU ]UXRd这里错误

这是加密代码:

private void encrypt_btn_Click(object sender, EventArgs e)
{
    int keynum = Convert.ToInt32(key_txt.Text);
    string orginalmessage = inputorginaltxt.Text;
    outputCiphertxt.Text = doEncryption(orginalmessage, keynum);
}

private static string doEncryption(string input, int key)
{
    string output = string.Empty;

    for (int i = 0; i < input.Length; i++)
    {
        if (char.IsLetter(input[i]) && char.IsUpper(input[i]))
        {
            char ch = (char)((((input[i] + key) - 'A') % 26) + 'A');
            output += ch;
        }
        else if (char.IsLetter(input[i]) && char.IsLower(input[i]))
        {
            char ch = (char)((((input[i] + key) - 'a') % 26) + 'a');
            output += ch;
        }
        else if (char.IsNumber(input[i]))
        {
            char ch = (char)((((input[i] + key) - '0') % 10) + '0');
            output += ch;
        }
        else if (char.IsLetter(input[i]))
        {
            char d = char.IsUpper(input[i]) ? 'A' : 'a';
            char ch = (char)((((input[i] + key) - d) % 26) + d);
            output += ch;
        }
        else if (!char.IsWhiteSpace(input[i])) // all alphabets
        {
            char ch = (char)((((input[i] + key) - '!') % 95) + '!');
            output += ch;
        }
        else
            output += input[i];
    }
    return output;
}

private void key_txt_TextChanged(object sender, EventArgs e)
{
    for (int i = 0; i < key_txt.Text.Length; ++i)
    {
        if (!char.IsNumber(key_txt.Text[i])
            || (Convert.ToInt32(key_txt.Text) < 1
                ||  Convert.ToInt32(key_txt.Text) > 25))
        {
            MessageBox.Show(
                "Incorrect key, must be enter a value in the range 1 to 25 ",
                "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            key_txt.Clear();
        }
    }
}

这里的错误码解密:

private void decrypt_btn_Click(object sender, EventArgs e)
{
    int keynum = Convert.ToInt32(key_txt.Text);
    string Plainmessage = outputCiphertxt.Text;
    outputPlaintxt.Text = doDecryption(Plainmessage, keynum);

}

private static string doDecryption(string input, int key)
{
    string output2 = string.Empty;

    for (int i = 0; i < input.Length; i++)
    {
        if (char.IsLetter(input[i]) && char.IsUpper(input[i]))
        {
            char ch = (char)((((input[i] - key) - 'A') % 26) + 'A');
            output2 += ch;

        }
        else if (char.IsLetter(input[i]) && char.IsLower(input[i]))
        {
            char ch = (char)((((input[i] - key) - 'a') % 26) + 'a');
            output2 += ch;
        }
        else if (char.IsNumber(input[i]))
        {
            char ch = (char)((((input[i] - key) - '0') % 10) + '0');
            output2 += ch;
        }
        else if (char.IsLetter(input[i]))
        {
            char d = char.IsUpper(input[i]) ? 'A' : 'a';
            char ch = (char)((((input[i] - key) - d) % 26) + d);
            output2 += ch;
        }
        else if (!char.IsWhiteSpace(input[i])) // all alphabets
        {
            char ch = (char)((((input[i] - key) - '!') % 95) + '!');
            output2 += ch;
        }
        else
            output2 += input[i];
    }
    return output2;
}
}

加密:

Hello world

键: 20

输出: Byffi qilfx

解密:

Byffi qilfx

键: 20

输出: .eRRU ]UXRd 这里错误

【问题讨论】:

  • 当你减去一个键时,你可能会得到一个负数,当你依赖模运算符产生一个正值时,这可能会导致问题。尝试使用添加模数的技巧:例如 (input[i] - key - 'A' + 26) % 26。将等式中的每个字符也视为unsigned char 可能是个好主意。我不知道 C# 是如何工作的,但是您将此问题标记为 C,所以这就是我在 C 中所做的。
  • 欢迎来到 SO。请仅添加与您的问题实际相关的标签。您的问题中没有 C 代码。 C 和 C# 是非常不同的语言。我也看不出这可能与winforms有什么关系。添加不相关的标签被认为是垃圾邮件,应该避免。

标签: c# windows caesar-cipher


【解决方案1】:

让我们从提取方法开始

  private static char Rotate(char value, int shift, Range range) {
    int mod = (range.End.Value - range.Start.Value + 1);

    return (char) (range.Start.Value + 
      ((value - range.Start.Value + shift % mod) % mod + mod) % mod);
  }

然后就可以放一个很简单的加解密例程了:

 private static string doEncryption(string input, int key) { 
   if (input == null)
     return input;

   return string.Concat(input.Select(c =>
       c >= 'a' && c <= 'z' ? Rotate(c, key, 'a'..'z') 
     : c >= 'A' && c <= 'Z' ? Rotate(c, key, 'A'..'Z') 
     : c >= '0' && c <= '9' ? Rotate(c, key, '0'..'9') 
     : c));
 }

 private static string doDecryption(string input, int key) => 
   doEncryption(input, -key);

演示: (fiddle)

  string[] tests = new string[] {
    "Hello world",
    "key",
    "20",
    "output",
    "Byffi qilfx",
  };

  int key = 20;

  string result = String.Join(Environment.NewLine, tests
    .Select(test => (plain: test, code: doEncryption(test, key)))
    .Select(pair => $"{pair.plain,-12} => {pair.code,-12} => {doDecryption(pair.code, key)}"));

  Console.Write(result);

结果:

Hello world  => Byffi qilfx  => Hello world
key          => eys          => key
20           => 20           => 20
output       => ionjon       => output
Byffi qilfx  => Vszzc kcfzr  => Byffi qilfx

请注意,您的代码

    else if (!char.IsWhiteSpace(input[i])) // all alphabets
    {
        char ch = (char)((((input[i] + key) - '!') % 95) + '!');
        output += ch;
    }

有一个逻辑错误:如果input[i] + key是一些字母数字(例如当input[i] == '#'key == 20我们@ 987654330@)它将被解码为字母或数字('7' 将被解密为7),而不是所需的符号(#

【讨论】:

  • 如何解决这个错误,我注意到当密钥设置为小于5时,解密是正确的
  • @Zeze Zezo:(char)((((input[i] - key) - d) % 26) + d); 不够:如果(input[i] - key) - d) &lt; 0 你会有问题。应该是(char)((((input[i] - d) - key % 26 + 26) % 26) + d);。看看我在Rotate 中的实现:((value - range.Start.Value + shift % mod) % mod + mod) % mod);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2021-06-09
  • 2022-09-27
  • 2014-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多