Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Probem with Caesar Cipher Code

Discussion in 'Scripting' started by JonnyDoeInWisco, Feb 14, 2015.

  1. JonnyDoeInWisco

    JonnyDoeInWisco

    Joined:
    Jun 2, 2014
    Posts:
    22
    Im making a caesar cipher program in Unity using NGUI. The program has a text area where you enter text which you can either encrypt or decrypt, both encrypt and decrypt have their own button. Then you have a small text field to enter the cipher, a number 1 -26. I have hooked up the buttons to test them, and they work, they call the Caesar method and seem to return null. This has to be the problem, but Im missing the solution here. Here is the code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class Cipher : MonoBehaviour {
    4.    
    5.      public Transform CipherInputBox;
    6.      public Transform TextField;
    7.      public string textYouTyped;
    8.      public int cipherYouTyped;
    9.    
    10.      public string Caesar(string text, int cipher)
    11.      {
    12.          print("Caesar was called");
    13.          char[] buffer = text.ToCharArray();
    14.          for (int i = 0; i < buffer.Length; i++)
    15.          {
    16.              // Letter.
    17.              char letter = buffer[i];
    18.              // Add shift to all.
    19.              letter = (char)(letter + cipher);
    20.              // Subtract 26 on overflow.
    21.              // Add 26 on underflow.
    22.              if (letter > 'z')
    23.              {
    24.                  letter = (char)(letter - 26);
    25.              }
    26.              else if (letter < 'a')
    27.              {
    28.                  letter = (char)(letter + 26);
    29.              }
    30.              // Store.
    31.              buffer[i] = letter;
    32.          }
    33.          return new string(buffer);
    34.        
    35.      }
    36.      public void EncryptMessage() {
    37.          print("Encrypt Message Called");
    38.          string caesarSays = Caesar(textYouTyped, cipherYouTyped);
    39.          print("Caesar was finished");
    40.          print(caesarSays);
    41.        
    42.      }
    43.      public void DecryptMessage() {
    44.          print("Decrypt Message Called");
    45.          string caesarSays = Caesar(textYouTyped, -cipherYouTyped);
    46.          print("Caesar was finished");
    47.          print(caesarSays);
    48.      }
    49. }
    I would also like to print out the coded/decoded message into the text box, any help with that would save some time. Thanks guys.
     
  2. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    Wild assed guess:

    The values for
    textYouTyped and/or cipherYouTyped are not being assigned.

    What is the result if you try ;
    Code (CSharp):
    1.  
    2. public void EncryptMessage() {
    3.          print("Encrypt Message Called");
    4.         Debug.Log(textYouTyped);
    5.         Debug.Log(cipherYouTyped.toString());
    6.         string caesarSays = Caesar(textYouTyped, cipherYouTyped);
    7. // .....
    8. )
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,498
    I tried your script and hand-coded external calls to the decipher/encipher triggered by my own uGUI button. Your de/enciphering worked fine, as expected. I hand-filled in the textYouTyped field and set the cipherYouTyped and it would work just fine.

    Keep in mind your script only works for a-z (lowercase). Not sure what it would do outside that range (like with uppercase or space for instance). In fact, if it got a space, it would detect it is less than 'a' and return space (32) minus 26 as the character, which I think is ^H... might want to do a little more value error checking in your loop there.
     
  4. JonnyDoeInWisco

    JonnyDoeInWisco

    Joined:
    Jun 2, 2014
    Posts:
    22
    I had some methods for testing that that I didnt include, and it does pass them to the console. On both the encrypt and decrypt methods, it does everything. The problem is that when it prints the caesarSays, it just comes up blank in the console. So something is obviously going wrong when Caesar runs. Its also frustratuig because I had it somewhat working for a second, where it worked, but with A or T where spaces should be. So it would come out like: thisTisTaTtest. Maybe it has something to do with the char array?
     
  5. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    You will also have issues with your cypher/dechpher of the user uses Uppercase characters or spaces.

    added:
    ahhh, Kurt mentioned this while I was reading your cypher code.
     
  6. JonnyDoeInWisco

    JonnyDoeInWisco

    Joined:
    Jun 2, 2014
    Posts:
    22
    So it's not in the script but in how its wired together? Do you know how I could convert the text to all lowercase on submission?
     
  7. JonnyDoeInWisco

    JonnyDoeInWisco

    Joined:
    Jun 2, 2014
    Posts:
    22
    Ok I just tried it out by handfilling the parameters. It works, but yes for the uppercase it printed an 'n' instead of 'T'. It still has the 'T' between the words as well. Now Im just exponentially more confused. Is the caesarSays variable the wrong type or something?
     
  8. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    Your issue is caused by not using the full printable character set(32-255);

    Try something like this perhaps
    note: this is a console app, so just grab the helper.

    Code (CSharp):
    1. using System;
    2. using System.Text;
    3.  
    4. namespace ConsoleApplication_CaesarCipher
    5. {
    6.     internal class Program
    7.     {
    8.         private static void Main(string[] args)
    9.         {
    10.             int shifter = 14;
    11.  
    12.             string result = CaesarEncryptDecrypt("Unity Test", shifter);
    13.             Console.WriteLine(result);
    14.             Console.WriteLine(CaesarEncryptDecrypt(result, shifter, false));
    15.             Console.ReadKey();
    16.         }
    17.  
    18.         public static string CaesarEncryptDecrypt(
    19.             string input,
    20.             int shift,
    21.             bool encrypt = true)
    22.         {
    23.             if (!encrypt) {
    24.                 shift *= -1;
    25.             }
    26.             StringBuilder sb = new StringBuilder();
    27.             for (int i = 0; i < input.Length; i++) {
    28.                 if (input[i] > 31 &&
    29.                     input[i] < 256) {
    30.                     sb.Append((char) ((((input[i] + shift) - 32) % 224) + 32));
    31.                 }
    32.                 else {
    33.                     sb.Append(input[i]);
    34.                 }
    35.             }
    36.             return sb.ToString();
    37.         }
    38.     }
    39. }
     
  9. JonnyDoeInWisco

    JonnyDoeInWisco

    Joined:
    Jun 2, 2014
    Posts:
    22
    Hmm, its having problems with the ciphering/deciphering. A lot of symbols coming up instead of letters. I'll fiddle around with it for a while. I have it working perfectly in a python script, I just have no experience translating python to C#....There isnt any easy solution for that is there?
     
  10. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    I haven't seen a translator for python to C# ...

    What is the python code you want to translate ?
     
  11. JonnyDoeInWisco

    JonnyDoeInWisco

    Joined:
    Jun 2, 2014
    Posts:
    22
    It's a working Caesar Cipher, but it runs text based... Here it is:
    Code (CSharp):
    1. #Caesar Cipher
    2.  
    3. MAX_KEY_SIZE = 26
    4.  
    5. def getMode():
    6.     while True:
    7.         print('Do you wish to encrypt, decrypt, or brute force a message?')
    8.         mode = input().lower()
    9.         if mode in 'encrypt e decrypt d brute b'.split():
    10.             return mode
    11.         else:
    12.             print('Enter either "encrypt" or "e", "decrypt" or "d", or "brute" or "b".')
    13.  
    14. def getMessage():
    15.     print('Enter your message: ')
    16.     return input()
    17.  
    18. def getKey():
    19.     key = 0
    20.     while True:
    21.         print('Enter the key number (1-%s)' % (MAX_KEY_SIZE))
    22.         key = int(input())
    23.         if (key >= 1 and key <= MAX_KEY_SIZE):
    24.             return key
    25.  
    26. def getTranslatedMessage(mode, message, key):
    27.     if mode[0] == 'd':
    28.         key = -key
    29.     translated = ''
    30.  
    31.     for symbol in message:
    32.         if symbol.isalpha():
    33.             num = ord(symbol)
    34.             num += key
    35.  
    36.             if symbol.isupper():
    37.                 if num > ord('Z'):
    38.                     num -= 26
    39.                 elif num < ord('A'):
    40.                     num += 26
    41.             elif symbol.islower():
    42.                 if num > ord('z'):
    43.                     num -= 26
    44.                 elif num < ord('a'):
    45.                     num += 26
    46.  
    47.             translated += chr(num)
    48.         else:
    49.             translated += symbol
    50.     return translated
    51.  
    52. mode = getMode()
    53. message = getMessage()
    54. if mode[0] != 'b':
    55.     key = getKey()
    56.  
    57. print('Your translated text is: ')
    58. if mode[0] != 'b':
    59.     print(getTranslatedMessage(mode, message, key))
    60. else:
    61.     for key in range(1, MAX_KEY_SIZE + 1):
    62.         print(key, getTranslatedMessage('decrypt', message, key))
    ):
     
  12. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    It's a while since I played with Python but that looks like it will translate spaces and numbers and punctuation without change and retain translated Uppercase characters in the translation.

    That should be fairly easy to translate.
    Looks like a great learning exercise.
     
  13. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    Perhaps have a play with this:
    The code is not pretty, but you should be able to follow the translation

    Code (CSharp):
    1. using System;
    2. using System.Text;
    3.  
    4. namespace ConsoleApplication_CaesarCipher
    5. {
    6.     internal class Program
    7.     {
    8.         private static void Main(string[] args)
    9.         {
    10.             int shifter = 13;
    11.             string input = "Unity Test15.";
    12.             string result = CaesarShift(input, shifter);
    13.             Console.WriteLine(result);
    14.             Console.WriteLine(CaesarShift(result, -shifter));
    15.             Console.ReadKey();
    16.         }
    17.  
    18.         public static string CaesarShift(string input, int shift)
    19.         {
    20.             StringBuilder translated = new StringBuilder(input.Length);
    21.  
    22.             char[] charArray = input.ToCharArray();
    23.             int charCode;
    24.  
    25.             for (int i = 0; i < charArray.Length; i++)
    26.             {
    27.                 char c = charArray[i];
    28.                 if (char.IsLetter(c))
    29.                 {
    30.                     charCode = c + shift;
    31.                     if (char.IsUpper(c))
    32.                     {
    33.                         if (charCode > 90) //'Z'
    34.                         {
    35.                             charCode -= 26;
    36.                         }
    37.                         else if (charCode < 65) //'A'
    38.                         {
    39.                             charCode += 26;
    40.                         }
    41.                     }
    42.                     else if (char.IsLower(c))
    43.                     {
    44.                         if (charCode > 122) //'z'
    45.                         {
    46.                             charCode -= 26;
    47.                         }
    48.                         else if (charCode < 97) //'a'
    49.                         {
    50.                             charCode += 26;
    51.                         }
    52.                     }
    53.                     translated.Append((char) charCode);
    54.                 }
    55.                 else
    56.                 {
    57.                     translated.Append(c);
    58.                 }
    59.             }
    60.             return translated.ToString();
    61.         }
    62.     }
    63. }
     
    Last edited: Feb 14, 2015
  14. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    Perhaps add this to keep the shift value in the range -26 <--> 26
    shift = shift % 26;

    Code (CSharp):
    1.        
    2. public static string CaesarShift(string input, int shift)
    3.         {
    4.             StringBuilder translated = new StringBuilder(input.Length);
    5.             shift = shift % 26;
    6.             char[] charArray = input.ToCharArray();
    7.             int charCode;
    8. ///............................
     
  15. JonnyDoeInWisco

    JonnyDoeInWisco

    Joined:
    Jun 2, 2014
    Posts:
    22
    Awesome. With some tweaking it's working perfectly now. Now I just need to get it to print out into the text box. Thanks for the help