Caesar Cipher Shift (using alphabet array)

元气小坏坏 提交于 2019-11-29 15:29:49

I played a bit with your code. The following gives you the solution, but you have to take care: you couldonly use capital letters, because theres a difference in upper and lower charts. I used the ToUpper() method. Works fine for me. I think that's what your problem was.

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

I took a look at your code and made a slight adjustment. First of all, I converted it to a method that lets you pass in the string and the amount you want to shift, so that you can either call it in a loop from 0 to 25 to see all the permutations, or you can just get a single value. I also check to see if each character is actually in the array, and if it isn't, then don't change it (in your code you were only checking for '\' and ' ' characters:

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

But another way to do this that works for upper AND lower case, and which is less code, is to simply test if char.IsLetter(character), and then shift the ASCII value of the character within the same 0-25 range.

For example, this does the same as the code above, only it works for lower case letters as well. The difference here is that before we compare the character to our lowest valued character ('a' or 'A'), we test if char.IsLower() first. This way we stay within the ASCII range for this character set:

/// <summary>
/// This method takes the input string and shifts all letter characters 
/// to the left (subtracts) by the amount specified in shiftAmount, so 
/// if shiftAmount = 1, then 'M' becomes 'L', and 'a' becomes 'z'.
/// </summary>
/// <param name="input">The input string to apply changes to</param>
/// <param name="shiftAmount">A value from 0 to 25, used to shift the characters</param>
/// <returns>The modified (shifted) string</returns>
public static string ShiftText(string input, int shiftAmount)
{
    if (input == null) return null;

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

    var result = string.Empty;

    // Loop through input and update result with shifted letters
    foreach (var character in input)
    {
        if (!char.IsLetter(character))
        {
            // If the character isn't a letter, don't change it
            result += character;
        }
        else
        {
            var newChar = (char) (character - shiftAmount);
            // Adjust newChar to stay within this character range
            if (newChar < (char.IsLower(character) ? 'a' : 'A')) newChar += (char) 26;
            result += newChar;
        }
    }

    return result;
}
Burak Karasoy

Why don't you just use character's ASCII values. I would convert ciphertext to lower case first. For example a's asci value is 97. I would write a method to extract 97 every characters so a=0,b=1..... z=25. Then for every character in your ciphertext get -3 shifted value of that char.For example input char d should return value 0 which corresponds a.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!