可以在一行中写一个ROT13吗?

时间:2013-09-11 10:46:43

标签: c# encryption rot13

我有以下代码,我希望将其视为oneliner。但是,由于我对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);
}

我很抱歉给您带来不便,只是想了解更多有关这种漂亮语言的内容:)

4 个答案:

答案 0 :(得分:17)

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

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;            
}

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

答案 1 :(得分:6)

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

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;
}

答案 2 :(得分:5)

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

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 :(得分:1)

另一个替代版本:

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)) }