C# 如何简化基本凯撒移位加密算法c的实现?

C# 如何简化基本凯撒移位加密算法c的实现?,c#,C#,所以我最近决定我的编码风格有点笨重。问题是,我似乎永远都无法达到这样一个阶段:我可以找到将其简化为更少行、更高效代码的方法 前几天,我在一个团队中编写代码,试图用TDD编写一个单词包装特性。当我坐在驾驶座上时,我大部分时间都在处理String.Split()和if语句这个和那个。和我一起编写代码的那个家伙问我为什么这么复杂,他使用了简单的递归一行程序,该程序返回所需的值,并且在完成时有一些条件将他从递归循环中引导出来 因此,我的问题是——下面是我编写的一些代码,它只使用小写字母,不使用空格,对字

所以我最近决定我的编码风格有点笨重。问题是,我似乎永远都无法达到这样一个阶段:我可以找到将其简化为更少行、更高效代码的方法

前几天,我在一个团队中编写代码,试图用TDD编写一个单词包装特性。当我坐在驾驶座上时,我大部分时间都在处理String.Split()和if语句这个和那个。和我一起编写代码的那个家伙问我为什么这么复杂,他使用了简单的递归一行程序,该程序返回所需的值,并且在完成时有一些条件将他从递归循环中引导出来

因此,我的问题是——下面是我编写的一些代码,它只使用小写字母,不使用空格,对字符串输入进行凯撒移位加密。单元测试通过了,我相信我已经实现了可能出现的各种条件

简而言之,你们将如何简化下面的代码以使其更具可读性和效率

我非常感谢您在这方面的帮助,因为在一天结束时,我需要让我的编码风格变得不那么冗长和简单,并且无法找到最佳的开始位置

干杯

C#中的代码:

公共静态字符串加密(字符串输入字符串,int-shiftPattern)
{
StringBuilder sb=新的StringBuilder();
字符[]字母表={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
//y=x+3(26型)
foreach(inputString.ToLower()中的var字母)
{
如果(!字母表包含(字母))
{
return“示例集中没有“+字母+”字符,请确保您只使用字母”;
}
var res=数组.IndexOf(字母表,字母)+(移位模式%26);
如果(res>=26)
{
res=res-字母表长度;
某人附加(字母表[res]);
}
else if(res<0)
{
res=字母表。长度+res;
某人附加(字母表[res]);
}
其他的
某人附加(字母表[res]);
}
使某人返回字符串();
}
1.-将某人附加(字母[res])仅在条件之外附加一次。
2、考虑抛出异常,而不是返回消息…因此,稍后您可以轻松地检查操作是否正常工作。如果你的字母表中没有字符,你也应该考虑让字符“AS”。它将允许您处理空格等。
3.-检查最后一个条件是否确实必要。乍一看。。。看起来它可以安全移除。。。所以请确认一下。我们可以添加Math.Abs函数,以避免移位模式中出现负数问题。
-在一些地方你使用字母表。长度,在其他地方你使用26。始终使用字母表。长度。
5.-不要检查(res>=26),您可以直接执行MOD操作

    public static string Encrypt(string inputString, int shiftPattern)
            {
                StringBuilder sb = new StringBuilder();

                char[] alphabet = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };

                //y = x + 3 (mod 26)
                foreach (var letter in inputString.ToLower())
                {
                    if (!alphabet.Contains(letter)) //Consider throwing and exception instead
                    {
                        return "The " + letter + " Character was not in the sample set, please ensure you only use letters";
                    }

                    var res = Array.IndexOf(alphabet, letter) + (Math.Abs(shiftPattern) % alphabet.Length);
                    res = res % alphabet.Length
                    sb.Append(alphabet[res]);
                }
                return sb.ToString();
            }

我建议如下:

  • 在两种或两种以上的情况下,使用开关-case
  • 如果使用3.0或更高版本,则使用
    var
    代替char[]或任何变量声明
  • 使用lambda表达式避免For和Foreach循环
  • 使这些方法成为静态的,并将其放在一些可以全局共享的公共类中

  • 了解更多的良好实践。按照jetbrains的Resharper工具操作,无需保存完整的字母表列表。
    另外,如果您不支持空格,那么您的消息将像罗马拉丁语一样,没有空格

        public static string Encrypt(string inputString, int shiftPattern)
        {
            StringBuilder sb = new StringBuilder();
            foreach(char letter in inputString.ToLower())
            {
                int encryptedValue = 0;
                if (letter == ' ')
                {
                    encryptedValue = ' ';
                }
                else
                {
                    encryptedValue = (((letter - 'a') + shiftPattern) % 26) + 'a';
                }
    
                sb.Append((char)encryptedValue);
            }
            return sb.ToString();
        }
    

    对算法进行了一些更改:

    static char[] alphabet = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
    
    public static string Encrypt(string inputString, int shiftPattern)
    {
        if (inputString == null) return null;
        if (shiftPattern <= 0)
        {
            shiftPattern = alphabet.Length + shiftPattern % alphabet.Length;
        }
    
        var chars = inputString.Select(c =>
        {
            var index = Array.IndexOf(alphabet, char.ToLower(c));
            if (index == -1) return c;
    
            var result = alphabet[(index + shiftPattern) % 26];
            return char.IsLower(c) ? result : char.ToUpper(result);
        });
    
        return new string(chars.ToArray());
    }
    
    静态字符[]字母表={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    公共静态字符串加密(字符串输入字符串,int-shiftPattern)
    {
    if(inputString==null)返回null;
    if(移位模式)
    {
    var index=Array.IndexOf(字母表,char.ToLower(c));
    如果(索引==-1)返回c;
    var结果=字母表[(索引+移位模式)%26];
    返回char.IsLower(c)?结果:char.ToUpper(结果);
    });
    返回新字符串(chars.ToArray());
    }
    
    • 管理空字符串大小写
    • 无法识别的字符按原样保存(在密码中有争议…)
    • 只需使用linq而不是老式的循环和构建器
    • 管理大写字母
    • 更短,但仍然可以理解,没有问题
    • 为了清晰起见,我将返回和选择分开,如果返回。。。Select line没有超过代码基的列限制,我会将两者结合起来

    您可以在一行代码中删除for循环中的数组和所有内容

    输入:僵尸和移位1


    输出:apncjf

    我建议,他们会给你想要的。+1雪熊。。。我不知道codereview!:达-不知道那个网站。谢谢你的提醒。(res<0)如果你传入一个负数,比如-150,我知道这不太可能在这种算法中,因为大多数人会移位26,但以防万一。好的,然后我将编辑代码,在移位模式中添加一个Math.Abs并删除条件。我还删除了(res>=26)检查。我们可以直接做一个模块操作。不管这个数字是否大于26。好吧,我已经根据你建议的实现进行了返工,所有测试都通过了一级。如果我使用-15转换,我希望“mlylyl”会出现在另一端,但是我得到的是“qpcpcp”。我不确定我是否同意所有这些:1。不过,他没有做平等性检查——你能把case>=26换成case<0吗?2.在我看来,最好将基本类型,如
    char
    保留为3。但这通常可读性较差,而且(我认为)效率也较低——如果您返回的是一个新的收藏,但没有
    static char[] alphabet = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
    
    public static string Encrypt(string inputString, int shiftPattern)
    {
        if (inputString == null) return null;
        if (shiftPattern <= 0)
        {
            shiftPattern = alphabet.Length + shiftPattern % alphabet.Length;
        }
    
        var chars = inputString.Select(c =>
        {
            var index = Array.IndexOf(alphabet, char.ToLower(c));
            if (index == -1) return c;
    
            var result = alphabet[(index + shiftPattern) % 26];
            return char.IsLower(c) ? result : char.ToUpper(result);
        });
    
        return new string(chars.ToArray());
    }
    
            StringBuilder sb = new StringBuilder();
            foreach (var letter in inputString.ToLower())
                sb.Append((char)((((letter - 'a') + shiftpattern)%26) + 'a'));