c# - 为什么我的字符串在凯撒密码期间发生变化?

标签 c# algorithm linq testing

我制作凯撒密码是为了娱乐和训练。我在测试中发现了一个“奇怪”的行为。

最后两行返回一个错误。他们不是“好的”。我不知道我哪里错了。

您可以在 dotnetfiddle 上试用我的完整代码.

输出

0000 RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ok
0001 SboepnVujm.HfuSboepnTusjoh(); // ? RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ok
[...]
0030 VerhsqYxmp.KixVerhsqWxvmrk(); // ? RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ok
0031 WfsitrZynq.LjyWfsitrXywnsl(); // ? RandomUtil.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ok
0032 Xgtjus[zor.MkzXgtjusYzxotm(); // ? Random[til.GetRandomString(); // ? RandomUtil.GetRandomString(); // ? ko
0033 Yhukvt\{ps.Nl{YhukvtZ{ypun(); // ? Random\{il.Ge{RandomS{ring(); // ? RandomUtil.GetRandomString(); // ? ko
ok 32
ko 2

测试

public static void Main()
{
    int okCounter = 0;
    const string str = "RandomUtil.GetRandomString(); // ?";
    int iter = str.Length;
    for (int i = 0; i < iter; i++)
    {
        var e = CaesarCipher.Encrypt(str, i);
        var d = CaesarCipher.Decrypt(e, i);
        Console.WriteLine("{0:D4} {1} {2} {3} {4}", i, e, d, str, str == d ? "ok" : "ko");
        if (str == d)
            okCounter++;
    }

    Console.WriteLine("ok " + okCounter);
    Console.WriteLine("ko " + (iter - okCounter));
}

凯撒密码类

public static string Encrypt(string input, int code)
{
    return RunCipher(input, code);
}

public static string Decrypt(string input, int code)
{
    return RunCipher(input, -code);
}

private static string RunCipher(string letters, int shift)
{
    return new String(MoveLetters(letters, shift).ToArray());
}

private static IEnumerable<char> MoveLetters(string letters, int shift)
{
    return
        from letter in letters
        let l = (char)(letter + shift)
        let diffCase = Char.IsLower(letter) ? 0 : 32
        let max = 'z' - diffCase
        let min = 'a' - diffCase
        let isAsciiLetter = letter >= min && letter <= max
        select isAsciiLetter ? (char)(l > max ? l - 26 : l < min ? l + 26 : l) : letter;
}

最佳答案

在 MoveLetter() 中你有行

let l = (char)(letter + shift)

当 shift > 26 时,它会移出字母字符代码范围

所以你至少需要把它改成

let l = (char)(letter + shift%26)

或在您的代码中添加检查以避免 shift <= 0 和 shift >= 26,因为它们在凯撒密码中没有多大意义

关于c# - 为什么我的字符串在凯撒密码期间发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28139114/

相关文章:

c# - 在单个执行点运行多个 IQueryable

c# - 如何从 Request.CreateErrorResponse 检索异常消息?

algorithm - 句子索引

.net - 从多个集合中获取特定元素组合排名的算法

c# - 如何使用 LINQ 对从文件加载的数据进行排序

c# - 使用 LINQ 从多维数组中提取特定值

c# - 如何在 Unity 中设置刚体的最大速度?

c# - 参数 varbinary 数据类型中的空值

C# WPF - 如何在 ListView 中拥有复选框?

php - 使用 Lanczo 算法调整 Web 图像大小 - 我应该使用哪种语言?