【问题标题】:Is it possible to write a ROT13 in one line?是否可以在一行中写一个ROT13?
【发布时间】:2013-09-11 10:46:43
【问题描述】:

我有以下代码,我希望将其视为单行代码。但是,由于我对 C# 非常陌生,因此我目前不知道如何执行此操作...

代码:

static string ROT13 (string input)
{
    if (string.IsNullOrEmpty(input)) return input;

    char[] buffer = new char[input.Length];

    for (int i = 0; i < input.Length; i++)
    {
        char c = input[i];
        if (c >= 97 && c <= 122)
        {
            int j = c + 13;
            if (j > 122) j -= 26;
            buffer[i] = (char)j;
        }
        else if (c >= 65 && c <= 90)
        {
            int j = c + 13;
            if (j > 90) j -= 26;
            buffer[i] = (char)j;
        }
        else
        {
            buffer[i] = (char)c;
        }
    }
    return new string(buffer);
}

对于给您带来的不便,我深表歉意,只是想进一步了解这种漂亮的语言 :)

【问题讨论】:

  • 只需将方法中的所有字符放在一行中即可。
  • 你有什么理由故意让事情变得不可读?
  • 完全不相关,但您可能想了解的另一件事是magic numbers 通常不是一件好事。正如 Save 所示,最好使用字符而不是它们的数值来更好地显示代码的作用。根据经验,任何代码的阅读量都是编写量的十倍以上。因此,您的目标应该始终是编写尽可能清晰易懂的代码,而不是尽可能多地使用巧妙的技巧。你可以在你拥有的东西起作用时进行优化。
  • 这个问题可以链接到stackoverflow.com/q/617647

标签: c# encryption rot13


【解决方案1】:

这个呢? 我只是碰巧有这个代码,它不是很漂亮,但它可以完成工作。 只是为了确保:一个班轮很有趣,但它们通常不会提高可读性和代码可维护性......所以我会坚持你自己的解决方案:)

static string ROT13(string input)
{
    return !string.IsNullOrEmpty(input) ? new string (input.ToCharArray().Select(s =>  { return (char)(( s >= 97 && s <= 122 ) ? ( (s + 13 > 122 ) ? s - 13 : s + 13) : ( s >= 65 && s <= 90 ? (s + 13 > 90 ? s - 13 : s + 13) : s )); }).ToArray() ) : input;            
}

如果您需要更多说明,请尽管询问。

【讨论】:

  • 感谢您的快速回复!我已经将代码粘贴到我的程序中,它工作得很好!我想我会更多地考虑使用 ? : 运算符。
  • 这是一个条件语句或只是一个 if ... then ... else ... 语句。 if 替换为布尔语句(条件) then 替换为 ?并且 else 被替换为 :。祝你好运,很高兴它对你有用!
【解决方案2】:

只是一个替代版本,它在比较中使用其他字符以使事情更“清晰”

static string ROT13(string input)
{
  return !string.IsNullOrEmpty(input) ? new string(input.Select(x => (x >= 'a' && x <= 'z') ? (char)((x - 'a' + 13) % 26 + 'a') : ((x >= 'A' && x <= 'Z') ? (char)((x - 'A' + 13) % 26 + 'A') : x)).ToArray()) : input;           
}

【讨论】:

    【解决方案3】:

    并不是真正的单行代码,但仍然比您的原始代码短,并且比其他答案更容易理解:

    static string Rot13(string input)
    {
        if(input == null)
            return null;
        Tuple<int, int>[] ranges = { Tuple.Create(65, 90), Tuple.Create(97, 122) };
        var chars = input.Select(x =>
        {
            var range = ranges.SingleOrDefault(y => x >= y.Item1 && x <= y.Item2);
            if(range == null)
                return x;
            return (char)((x - range.Item1 + 13) % 26) + range.Item1;
        });
    
        return string.Concat(chars);
    }
    

    另一个更好地表达 ROT13 中发生的事情的版本是:

    static string Rot13(string input)
    {
        var lowerCase = Enumerable.Range('a', 26).Select(x => (char)x).ToArray();
        var upperCase = Enumerable.Range('A', 26).Select(x => (char)x).ToArray();
        var mapItems = new[]
        {
            lowerCase.Zip(lowerCase.Skip(13).Concat(lowerCase.Take(13)), (k, v) => Tuple.Create(k, v)),
            upperCase.Zip(upperCase.Skip(13).Concat(upperCase.Take(13)), (k, v) => Tuple.Create(k, v))
        };
        var map = mapItems.SelectMany(x => x).ToDictionary(x => x.Item1, x => x.Item2);
    
        return new string(input.Select(x => Map(map, x)).ToArray());
    }
    
    static char Map(Dictionary<char, char> map, char c)
    {
        char result;
        if(!map.TryGetValue(c, out result))
            return c;
        return result;
    }
    

    【讨论】:

    • 如果你在顶级解决方案中只获得每个字符的 Int32 表示,请将return (char)((x - range.Item1 + 13) % 26) + range.Item1 更改为return (char)((x - range.Item1 + 13) % 26 + range.Item1)
    【解决方案4】:

    还有一个替代版本:

    static string ROT13(string input) { String.Join("", input.Select(x => char.IsLetter(x) ? (x >= 65 && x <= 77) || (x >= 97 && x <= 109) ? (char)(x + 13) : (char)(x - 13) : x)) }

    【讨论】:

      猜你喜欢
      • 2019-10-30
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 1970-01-01
      • 2019-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多