Caesar Cipher Shift(使用字母数组)

时间:2015-11-13 12:56:16

标签: c# arrays caesar-cipher

我目前正在C#中编写一个Caesar Cipher程序来完成我的任务,我遇到了问题。

我正在使用一个数组来接近这个任务,我存储了整个字母表,并且我声明了一个移位变量,它由数组中的字符索引定义 - for循环的迭代。移位计算在foreach循环中完成,该循环从从文本文件中读取的字符串中提取字符。 Foreach循环包含在for循环中,迭代输出每个可能的移位。

然而,问题是当我尝试通过我的移位变量的值访问数组中的字符时,程序似乎无法访问我想要的字符,它只输出相同的字符。原始字符串。

这是该程序的代码:

using System; 
using System.IO;

public class caesar_shift
{
    public static void Main()
    {
        string file = @"C:\Users\terasss2\Desktop\Programming and Data Structures\caesarShiftEncodedText.txt";      //String variable that stores a file location
        string encrypted_text = File.ReadAllText(file);     //String variable that contains the text from a file. To get the text, the method in a class SystemIO is ran to read the text. It expects a parameter, which is a file directory.
        string decoded_text = " ";
        int shift = 0;
        char character = '0';

        char[] alphabet = new char[26]{'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'};

        Console.WriteLine("The encrypted text is \n{0}", encrypted_text);       //Display the encrypted text

        for(int i = 0; i < alphabet.Length; i++)        //Start a loop which will display 25 different candidates of decipher
        {
            foreach(char c in encrypted_text)
            {
                character = c;

                if(character == '\'' || character == ' ')
                    continue;

                shift = Array.IndexOf(alphabet, character) - i;     //Define a shift which is the index of a character in an alphabet array, take away the itteration of this loop. Store the result in a variable

                if(shift <= 0)
                    shift = shift + 26;

                if(shift >= 26)
                    shift = shift - 26;

                character = alphabet[shift];    //Set the character to a shifted letter by accessing the array element of a value shift

                Console.WriteLine(character);

                decoded_text = decoded_text + character; 
             }  

            Console.WriteLine("\nShift {0} \n {1}",i + 1, decoded_text);

         }
       }
}

3 个答案:

答案 0 :(得分:3)

我用你的代码玩了一下。以下为您提供解决方案,但您必须小心:您只能使用大写字母,因为上下图表存在差异。我使用了ToUpper()方法。对我来说很好。我认为这就是你的问题所在。

public static void Main()
    {
        string encrypted_text = "BCD";     //String variable that contains the text from a file. To get the text, the method in a class SystemIO is ran to read the text. It expects a parameter, which is a file directory.
        string decoded_text = " ";
        int shift = 0;
        char character = '0';
        encrypted_text = encrypted_text.ToUpper();

        char[] alphabet = new char[26] { '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' };

        Console.WriteLine("The encrypted text is \n{0}", encrypted_text);       //Display the encrypted text

        for (int i = 0; i < alphabet.Length; i++)        //Start a loop which will display 25 different candidates of decipher
        {
            decoded_text = "";
            foreach (char c in encrypted_text)
            {
                character = c;

                if (character == '\'' || character == ' ')
                    continue;

                shift = Array.IndexOf(alphabet, character) - i;     //Define a shift which is the index of a character in an alphabet array, take away the itteration of this loop. Store the result in a variable
                if (shift <= 0)
                    shift = shift + 26;

                if (shift >= 26)
                    shift = shift - 26;


                decoded_text += alphabet[shift];
            }
            Console.WriteLine("\nShift {0} \n {1}", i + 1, decoded_text);
        }
    }

答案 1 :(得分:1)

我看了看你的代码,并做了些微调整。首先,我将其转换为一种方法,该方法可让您传递字符串和要转换的数量,以便您可以在025的循环中调用它以查看全部排列,或者您可以只获取一个值。我还要检查每个字符是否确实在数组中,如果不是,则不要更改它(在您的代码中,您仅检查'\'' '字符:< / p>

public static string ShiftText(string input, int shiftAmount)
{
    if (input == null) return null;

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

    shiftAmount %= 26; // Ensure shift is between 0 and 25

    var shiftedText = string.Empty;

    foreach (var character in input)
    {
        var index = Array.IndexOf(alphabet, character);

        if (index < 0)
        {
            // This character isn't in the array, so don't change it
            shiftedText += character;
        }
        else
        {
            var newIndex = index - shiftAmount;

            // If it's negative, wrap around to end of array
            if (newIndex < 0) newIndex += 26;

            shiftedText += alphabet[newIndex];
        }
    }

    return shiftedText;
}

执行此操作的另一种方法(适用于大写和小写,且代码较少)是简单地测试是否char.IsLetter(character),然后在相同的{{1}中移动字符的ASCII值}范围。

例如,这与上面的代码相同,仅适用于小写字母。此处的区别在于,在将字符与价值最低的字符(0-25'a')进行比较之前,我们先测试是否'A'。这样,我们就可以将此字符集保留在ASCII范围内:

char.IsLower()

答案 2 :(得分:0)

为什么不使用字符的ASCII值。我会先将密文转换为小写。例如a的asci值是97.我会写一个方法来提取97每个字符,所以a = 0,b = 1 ..... z = 25。然后,对于密文中的每个字符,获取该字符的-3移位值。例如,输入字符d应该返回值0,它对应于。