0

Hey so as an avid Stack Overflow user I now have to make my first post that because i've been having an issue recently where the letters I and Z are not being picked up by the program correctly and are now not being encrypted. Below is the code, any ideas would be great. Also please ignore the messy code xD love C# but hate organising code. Anyway thank you.

public static void mainMenu()
    {
        Console.Clear();
        Console.WriteLine("| Affine Cipher Program - Group 40 |");
        Console.WriteLine("*----------------------------------*");
        Console.WriteLine("\n\n 1) Encrypt \n 2) Decrypt \n 3) Crack");
        try
        {
            int menuEntry = Convert.ToInt32(Console.ReadLine());
            if (menuEntry == 1)
            {
                EncryptSettings();
            }
            else if (menuEntry == 2)
            {
                DecryptSettings();
            }
            else if (menuEntry == 3)
            {
                findKeySettings();
            }
        }
        catch
        {
            E0x0001("menuEntry");
        }
    }
    public static void EncryptSettings()
    {
        int[] valueA = new int[] { 1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25 };
        Console.Clear();
        Console.WriteLine("Please enter the plain text that you would like to encrypt");
        try
        {
            string pTextN = Console.ReadLine();
            string pText = String.Concat(pTextN.Where(c => !Char.IsWhiteSpace(c)));
            Console.WriteLine(pText);
            if (pText.Length == 0)
            {
                E0x0001("plainTextValue");
            }
            else
            {
                int num = 0;
                string[] chars = new string[] { "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("\nPlease select a value for Value A from the list below;");
                foreach (int n in valueA)
                {
                    Console.WriteLine(n);
                }
                int valA = Convert.ToInt32(Console.ReadLine());
                bool contNum = valueA.Contains(valA);
                if (contNum == true)
                {
                    Console.WriteLine("\nPlease enter any letter");
                    string valB = Console.ReadLine();
                    if(valB.Length > 0 && valB.Length < 2)
                    {
                        foreach (int chr1 in valB)
                        {
                            string c1 = Char.ConvertFromUtf32(chr1);
                            num = Array.IndexOf(chars, c1) + 1;
                            valB = char.ToUpper(valB[0]).ToString();
                        }
                        
                    }else
                    {
                        E0x0001("ValueB");
                    }
                    Console.WriteLine("The string " + pText + " will now be encrypted with the values " + valA + " and " + valB + ", Press any key to continue");
                    Console.ReadLine();
                    pText.ToUpper();
                    string[] cText = new string[] { };
                    foreach (int chr in pText)
                    {
                        Console.WriteLine("ASCII is :" + chr);
                        string c = Char.ConvertFromUtf32(chr);
                        c = char.ToUpper(c[0]).ToString();
                        Console.WriteLine("Letter is: " + c);
                        Console.WriteLine($"Index - {Array.IndexOf(chars, c) + 1}");
                        int workable = Array.IndexOf(chars, c) + 1;
                        //int final = workable * valA + num  % 26;
                        int final = workable * valA;
                        final = final + num;
                        final = final % 26 - 2;
                        
                        Console.WriteLine("Number: " + final + " Letter: " + chars.GetValue(final) + "\n");
                    }
                    Console.ReadLine();

                    //maths notes//
                    //Encryption
                    //cText == (pText * valA) + valB
                    //Decryption
                    //pText == (cText - valB) * valA^-1

                }
                else
                {
                    E0x0001("ValueA");
                }
            }
        }
        catch
        {
            E0x0001("Value");
        }

    }

The input case i have been using is the main input as "Missing" and the user input as 3 and a. This produces and error that in the console states the following; Exception thrown: 'System.IndexOutOfRangeException' in mscorlib.dll. After some more digging into the program and some very helpful comments i've seen that when this exeption gets called 'Index outside the bounds of the array' is also shown and with some more digging saw the HResult was -2146233080. This only made me more confused while looking at it. Finally the called arrays are; int[] valueA and string[] chars. The final thing, the actual program fails on Console.WriteLine("Number: " + final + " Letter: " + chars.GetValue(final) + "\n");. Any help is greatly appreciated!

!!!UPDATE!!!

My friend pointed out an issue in the code that fixed the program were i needed to change the way i added up the array value. The code now works! i will post the updated code if people are curious but thank you for all of your help!

  • 1
    Is it intentional that `valueA` does not contain 13? It looks a bit suspicious when what appears to be a sequence of odd numbers is missing a value. – Andrew Morton Feb 20 '22 at 19:11
  • 2
    Please give at least some sample input, expected and observed output. – Klaus Gütter Feb 20 '22 at 19:12
  • @KlausGütter ill get the data now and edit this coment, thank you EDIT: The input Missing fails at the first I with the generic error code that i set however in the console it says "Exception thrown: 'System.IndexOutOfRangeException' in mscorlib.dll" – OliverCole1 Feb 20 '22 at 19:28
  • @AndrewMorton So quick one, with the Affine Cypher you can't have the number 13 as the first number – OliverCole1 Feb 20 '22 at 19:38
  • 1
    Seems like a good opportunity to learn [how to debug your programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Klaus Gütter Feb 20 '22 at 19:56
  • @KlausGütter Thank you for the article, i gave it a read and implemented some of the things and am now left with 'Index outside the bounds of the array' and with some more digging saw the HResult was -2146233080? This i have tried to wrap my head around and i can't? sorry for the original post and how it was structured and thank you for the continued help :) – OliverCole1 Feb 20 '22 at 20:13
  • So did you use a debugger? Where (which line of code) does this exception occur? Which array was accessed? What was the value of the index used? How long is the array? – Klaus Gütter Feb 20 '22 at 20:16
  • @KlausGütter after trying to use the DebuggerVisualizer i went and resorted to switching on all compile warnings and when i saw the error and the program failed i saw the exeption thrown screen in visual studio. This is where i then dug into what was happening. The line of code that errors is 'Console.WriteLine("Number: " + final + " Letter: " + chars.GetValue(final) + "\n");' the arrays that was accessed are 1) 'string[] chars' and 2) 'int[] valueA'. The value i was expecting to see for the index (I) was 9 however with some digging found it was -2146233080. One array is 26 chars long other 12 – OliverCole1 Feb 20 '22 at 20:29
  • run you code, works for me, please give example of failing input – pm100 Feb 20 '22 at 23:07
  • 1
    As a side note, there are encryption tools built into .Net. It'll save you a lot of time, and the solutions already built are always going to be safer than the ones we as individuals can write. https://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp – Dan Rayson Feb 20 '22 at 23:36

1 Answers1

1

Well you are not helped by all the try catches, since they hide the actuall errors unless you print them fully.

Your code fails here

    int final = workable * valA;
   final = final + num;
    final = final % 26 - 2;

    Console.WriteLine("Number: " + final + " Letter: " + chars.GetValue(final) + "\n");

because final ends up being -2 when processing 'Z' (char.GetValue needs a positive integer)

  • workable is 26
  • valA is 19 (I entered that when prompted)
  • num is 26

I dont know how your algorithm works so cannot suggest a fix

pm100
  • 48,078
  • 23
  • 82
  • 145
  • Ahh ok fair enough, thank you for that! so the actual program is meant to be an Affine Cipher implementation so sadly i cant use a predefined lib or something like that. I am still very confused as to why Z would give -2 but ill do some more digging in the code and see if i can solve anything. Thank you so much for your help! – OliverCole1 Feb 21 '22 at 13:07
  • @OliverCole1 Z gives -2 becuase thats what your code says,29 * 19 + 26 = 520 , 520 % 26 = 0, 0 -2 = -2 – pm100 Feb 21 '22 at 17:19