如何将字符移动到某些点

时间:2013-07-24 08:07:26

标签: c#-4.0 encryption

我遇到一个问题,我需要SWAPmove个字符和整数。就像我有任何字符A。现在我有一些情况,比如

注意: - 必须使用字符A-Z和整数0-9

  1. A,现在我希望在我的程序运行时为此字符分配一些整数值,如果我为此字符指定值3,则A将成为D或者它只是移动到3个地方。

  2. 现在,如果我有一个像Y这样的字符而我添加4则会C表示Z之后它将再次从字符A开始。

  3. 相同条件我必须遵循Integer,如果我有9并且我们为它分配3然后它将变为2因为循环从0开始而不是从1.意味着我们必须只使用0-9整数。 / p>

  4. 我知道我使用错误的名字来提问,但我不知道我必须使用哪一行代表这类问题。

    希望你能理解我的问题。

    提前致谢。

4 个答案:

答案 0 :(得分:2)

尝试以下扩展方法,该方法执行以下操作:

  1. 它会创建2个词典,以加快alphabet
  2. 中的键查找速度
  3. 将解析inputString变量,将其拆分为moveString变量长度(或余数)长度的子串中
  4. 在每个子字符串上,它将评估每个字符,以便检测它是否为数字
  5. 如果它不是数字,则会使用swappedAlphabet键在int字典中查找值
  6. 如果是数字,则对数字和相应moveint值的总和应用模运算
  7. 最终聚合最终结果字符串中的所有字符
  8. 以下是代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    class Program
    {
        static void Main(string[] args)
        {
            string
                alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string inputString = "ABC123D", moveString = "12";
            var result = inputString.Swap(alphabet, moveString);
            Console.WriteLine(result);
        }
    }
    
    static class ExtensionMethods
    {
        public static Dictionary<TValue, TKey>
            SwapKeysValues<TKey, TValue>(this Dictionary<TKey, TValue> input)
        {
            var result = new Dictionary<TValue, TKey>();
            input.ToList().ForEach((keyValuePair) =>
            {
                result.Add(keyValuePair.Value, keyValuePair.Key);
            });
            return result;
        }
    
        public static string Swap(
            this string input,
            string alphabet,
            string move)
        {
            Dictionary<char, int> 
                alphabetDictionary = new Dictionary<char, int>();
    
            for (int i = 0; i < alphabet.Length; i++)
            {
                alphabetDictionary.Add(alphabet[i], i);
            }
    
            var swapedAlphabet = alphabetDictionary.SwapKeysValues();
            return Enumerable
                .Range(0, (int)Math.Ceiling(input.Length / (move.Length * 1M)))
                .ToList()
                .Aggregate<int, string>("", (s, i) =>
                {
                    var l = i * move.Length + move.Length;
                    var cInput = input.Substring(i * move.Length, 
                        (l > input.Length) 
                            ? input.Length - i * move.Length : move.Length);
                    return s + cInput
                .Select((c, index) =>
                {
                    int intCandidate;
                    if (!Int32.TryParse(c.ToString(), out intCandidate))
                    {
                        var length = (alphabetDictionary[c] +
                            Int32.Parse(move[index].ToString()));
                        return
                            swapedAlphabet[(alphabet.Length > length)
                                ? length : length % alphabet.Length];
                    }
                    else
                    {
                        var moveInt = Int32.Parse(move[index].ToString());
                        return Char.Parse(((intCandidate + moveInt) % 10)
                            .ToString());
                    }
                })
                .Aggregate<char, string>("", (a, b) => a + b);
                });
        }
    }
    

答案 1 :(得分:1)

这是使用您定义的限制实现Caesar Cipher的一种非常简单的方法。

var shift = 3;
var input = "HELLO WORLD 678";

var classAlphabets = new Dictionary<UnicodeCategory, string>
{
    { UnicodeCategory.SpaceSeparator, " " },
    { UnicodeCategory.UppercaseLetter, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
    { UnicodeCategory.DecimalDigitNumber, "0123456789" }
};

var encoded = input.ToUpperInvariant()
                   .Select(c => new { Alphabet = classAlphabets[Char.GetUnicodeCategory(c)], Character = c })
                   .Select(x => new { x.Alphabet, Index = x.Alphabet.IndexOf(x.Character) })
                   .Select(x => new { x.Alphabet, Index = x.Index + shift })
                   .Select(x => new { x.Alphabet, Index = x.Index % x.Alphabet.Length })
                   .Select(x => x.Alphabet.ElementAt(x.Index))
                   .Aggregate(new StringBuilder(), (builder, character) => builder.Append(character))
                   .ToString();

Console.Write(encoded);

// encoded = "KHOOR ZRUOG 901"

解码只是反转移位的一种情况。

答案 2 :(得分:1)

您拥有的另一种选择是依赖内置的character / integer类型,这些类型遵循您想要的顺序;另外考虑一下:如果你考虑上限,它会提供上限(“A”之后的“B”和“a”之后的“b”)。您唯一需要担心的是确保迭代将限制在A-Z / 0-9边界。示例代码:

public string moveChar(string inputChar, int noPos)
{
    string outChar = checkBoundaries(inputChar, noPos);

    if (outChar == "")
    {
        outChar = basicConversion(inputChar, noPos);
    }

    return outChar;
}

public string basicConversion(string inputChar, int noPos)
{
    return Convert.ToString(Convert.ToChar(Convert.ToInt32(Convert.ToChar(inputChar)) + noPos));
}

public string checkBoundaries(string inputChar, int noPos)
{
    string outString = "";

    int count1 = 0;
    do
    {
        count1 = count1 + 1;
        string curTemp = basicConversion(inputChar, 1);
        if (inputChar.ToLower() == "z" || curTemp.ToLower() == "z")
        {
            if (inputChar.ToLower() != "z")
            {
                noPos = noPos - count1;
            }

            inputChar = "a";
            outString = "a";
            if (inputChar == "Z" || curTemp == "Z")
            {
                inputChar = "A";
                outString = "A";
            }

            count1 = 1;
        }
        else if (inputChar == "9" || curTemp == "9")
        {
            if (inputChar != "9")
            {
                noPos = noPos - count1;
            }

            inputChar = "0";
            outString = "0";

            count1 = 1;
        }
        else
        {
            inputChar = curTemp;
            outString = inputChar;
        }
    } while (count1 < noPos);

    return outString;
}

它需要字符串(每个调用只有一个字符(字母或数字)),您只需使用:moveChar("current letter or number", no_of_pos_to_move)即可调用它。此版本仅用于“正向”/“向前”移动,但可以轻松编辑以解决相反的情况。

答案 3 :(得分:0)

凯撒密码可以更容易:

static char Encrypt(char ch, int code)
{
    if (!char.IsLetter(ch))
    {
        return ch;
    }
    char offset = char.IsUpper(ch) ? 'A' : 'a';
    return (char)(((ch + code - offset) % 26) + offset);
}

static string Encrypt(string input, int code)
{
    return new string(input.ToCharArray().Select(ch => Encrypt(ch, code)).ToArray());
}

static string Decrypt(string input, int code)
{
    return Encrypt(input, 26 - code);
}

const string TestCase = "Pack my box with five dozen liquor jugs.";

static void Main()
{
    string str = TestCase;

    Console.WriteLine(str);
    str = Encrypt(str, 5);
    Console.WriteLine("Encrypted: {0}", str);
    str = Decrypt(str, 5);
    Console.WriteLine("Decrypted: {0}", str);
    Console.ReadKey();
}