Joshua Hadabora 2104 Task 1 – Caesar Cipher Contents REQUIREMENTS ............................................................................................................................................... 1 DESIGN ............................................................................................................................................................ 2 VARIABLES ............................................................................................................................................................. 2 PSEUDO CODE ........................................................................................................................................................ 2 FLOWCHART ........................................................................................................................................................... 3 DEVELOPMENT CHOICES .................................................................................................................................. 3 TESTING ........................................................................................................................................................... 4 PLANNING ............................................................................................................................................................. 4 DEVELOPMENT ....................................................................................................................................................... 5 Test 1: Using the input function to get a string from the user. ...................................................................... 5 Test 2: Using a for loop and the range function to iterate through every letter of a string........................... 5 Test 3: Getting the ASCII code of a character................................................................................................. 6 Test 4: Changing a letter with an offset of 3. ................................................................................................. 7 Test 5: Disallowing encryption of numbers, spaces and special characters. .................................................. 8 Test 6: Wrapping letters around the alphabet. ........................................................................................................... 8 FINAL SOLUTION ................................................................................................................................................... 10 Test 1: Does an error appear when an offset that’s not in range is entered? .............................................. 10 Test 2: Putting in the alphabet in uppercase with an offset of 3 to test encryption. ................................... 12 Test 3: Decrypting the encrypted alphabet. ................................................................................................. 12 Test 4: Putting in a lowercase alphabet with a different offset of 12. ......................................................... 12 Test 5: Encrypting a full sentence. ............................................................................................................... 13 Test 6: Decrypting the encrypted full sentence. ........................................................................................... 13 RECAP ................................................................................................................................................................. 14 Development Tests ....................................................................................................................................... 14 FINAL SOLUTION TESTS........................................................................................................................................... 15 EVALUATION.................................................................................................................................................. 15 MEETING REQUIREMENTS....................................................................................................................................... 15 CONCEPTS ........................................................................................................................................................... 16 Brute Force ................................................................................................................................................... 16 CONCLUSION ........................................................................................................................................................ 17 Requirements This first task requires proof of designing, development, testing and evaluation of a program that encrypts strings based on an offset. The string can include special characters like numbers and symbols, but these will not be encrypted and will stay the same throughout the process of encryption. Uppercase letter will remain uppercase and lowercase will remain lowercase. (The alphabet must wrap around itself.) An error must also be thrown if the offset is less than -25 or greater than 25. (These numbers are chosen because they are the range of the alphabet.) The encrypted string will be displayed after this process. Page 1 Joshua Hadabora 2104 The string must not be blank. The offset must be an integer. Design This program will be run using the command line or a Python shell, and the string will be entered with a keyboard. Variables Variables are used to store data which can change while a program is being run. The variables used in the program will be: string The string that the user will input that will be encrypted. We only have to test the length of this to check if it was left blank by the user. newstring The final string given to the user when the encryption is done. The program will go through the user’s string letter by letter, and adding the encrypted version of the letter to this final string. offset An integer from the user that lets the computer know how much to encrypt the string by. firstuppercase, lastuppercase, firstlowercase, lastlowercase These variables aren’t really necessary, but are very useful. These variables act as constants (you cannot create constants on Python) which are used near the end of the code for wrapping letters. If you didn’t have these as constants we’d need to keep using numbers like ‘65’, ‘90’ and ‘122’ which would make our code harder to understand. newstring will be printed to the user if the program is successful. Pseudo Code INPUT encryption_string INPUT offset newstring = “” IF string is blank THEN THROWERROR “You cannot enter a blank string.” ELSE IF offset < -25 OR offset > 25 THEN THROWERROR “Your offset needs to be greater than -26 and less than 26.” ENDIF FOR every letter of encryption_string DO IF letter is in the alphabet THEN character_code = character code of letter character_code + offset Wrap character code around the alphabet if it goes out of bounds. (‘X’ must turn into ‘C’, not ‘]’) newstring += character from character_code ELSE newstring += letter ENDFOR RETURN newstring Page 2 Joshua Hadabora 2104 Flowchart Is the string blank? Is the offset less than 26 and greater than -26? Is this character a number, space or a special symbol? Is there any other letters remaining in the string? Development Choices For this task I used Python 3.4.1 and the IDLE GUI because it is a programming language that is very easy to program for, with access to tons of built in functions and is still a very powerful language. Built in functions I used include ord(), chr() and string.isalpha(), which help make programming easier because these functions do not need to be programmed as well. Programming these would make the code much less efficient, more bloated and would likely cause more errors in the code. Here are all the built-in features I took advantage of in Python: if An if statement tests a condition and executes a block of code if the condition is true. elif Page 3 Joshua Hadabora 2104 This is a variant of an if statement which only executes if its condition is true and the previous if statement was false. for A for loop executes a block of code multiple times, and creates a variable that goes through a list such as a range or a string for each loop. input The input function allows users to input their own data into the program. The program stops processing lines of code and the user is allowed to type in data. The function’s first parameter is a string which will be asked when the user is able to type. print The print function gives an output to the user in the console. int Converts a string into an integer, for example it could convert “2” to the number 2 or “5.36” to the number 5.36. int returns an error if the string does not look like it can be converted to a number. ord Gets the ASCII character code of a given character code. chr Turns an ASCII character code back into its character. raise Raises an exception that is either handled or showed to the user in red text. str.isalpha Check if the string only contains characters that are letters. We can give it a single character and it will check whether it is alphabetical or not. Testing Planning This code will be tested as it is developed as well as when the program is complete. Testing while developing will allow looking into interesting solutions that can be made to overcome problems the task has given and then adapting the solution to fit our context. These tests would also make sure one part of the code works before we continue any further. Testing the final solution will make sure that every aspect of the code that needs to work functions correctly and we have a finished program. Here are the tests we are going to carry out: Test No. 1 2 3 4 Development Tests Using the input function to get a string from the user. Using a for loop and the range function to iterate through every letter of a string. Getting the ASCII code of a character. Changing a letter with an offset of 3. Page 4 Joshua Hadabora 2104 5 6 Disallowing encryption of numbers, spaces and special characters. Wrapping letters around the alphabet. Test No. 1 2 3 4 5 6 Final Solution Tests Does an error appear when an offset that’s not in range is entered? Putting in the alphabet in uppercase with an offset of 3 to test encryption. Decrypting the encrypted alphabet. Putting in a lowercase alphabet with a different offset. Encrypting a full sentence. Decrypting the encrypted full sentence. Development Test 1: Using the input function to get a string from the user. The first thing we need to develop is a way to get inputs from the user. Without this, the program would just be useless. In Python, we can get input from a user with the input function which returns what the user entered as a string. This means that we can make a variable equal to what input returns, like this: We are expecting this piece of code to output to the console exactly what the user entered. Which is what happens, meaning that we’ve explored and successfully tested a method to get input from a user. 1 2 3 4 5 6 Test 2: Using a for loop and the range function to iterate through every letter of a string. A for loop is used in most programming language to iterate through a list. In python these lists can be numbers, strings and arrays for example. We’ll need to loop through every letter of a string to encrypt the whole string and there are two methods of doing this. One method would be to use a feature exclusive to Python that allows you to iterate actual strings. Another method would be to use the method for all other programming languages, going from 0 to the length of the string. An advantage of using this method is that we’d have access to the exact position of the character in the string. A disadvantage is that we would not have direct access to the character, since string for loops give you a character instead of that character’s position. In the end, I’ve decided to use for loops that give you the character’s position because it is much more familiar to me and will come in useful for the later tasks. We are expecting each letter to come up on the console in individual lines, and the position of that letter in the user’s string. Page 5 Joshua Hadabora 2104 Now we have also explored how to use for loops to iterate through a string, which will be useful when we are creating the encryption program. 1 2 3 4 5 6 Test 3: Getting the ASCII code of a character. To encrypt a string using offset, we’ll need the help of the ASCII table and character codes. In computers, each letter has its own character code. This is because computers only understand either 0 or 1 and don’t have a concept of letters and writing. So we give letters their own numbers so the computers can represent these codes as text. We can use this system to our advantage, because we can get the character code of a letter, add or take away from it, and turn it back into a letter. This will be explored next test. We are expecting this chunk of code to ask the user for a string, and give the user back a list of every character code in that string. Page 6 Joshua Hadabora 2104 The final outcome is a list of every character code in this string, which is what we need in order to encrypt. 1 2 3 4 5 6 Test 4: Changing a letter with an offset of 3. Next we are going to have to use a function that turns a character code back into a character. This is done with the chr function. With some simple arithmetic, we can easily change letters in a systematic way. For example, if we change capital B into it’s character code – 66, we can add an offset of 5 to it to make 71 and change this back to a letter to make a capital G. 1 2 3 4 5 This code changes the first letter the user enters with an offset of 3. This test program runs no problem with most letters, however starts breaking in a lot of different circumstances: This is not ideal, as entering a string with letters towards the end of the alphabet, spaces and special characters would make a lot of garbage symbols which the task does not want. It is clear that this task only wants letters to be encrypted in this program. This test may not be working so well, but the next two tests will fix this issue. 1 2 3 4 Page 7 5 6 Joshua Hadabora 2104 Test 5: Disallowing encryption of numbers, spaces and special characters. Adding str.isalpha to the code of the last test should now allow the program to check for numbers, spaces and special characters and print these characters out without encrypting them. Now the program finds characters which aren’t letters and keeps them the same. We could use validation to stop encryption of strings with numbers, spaces and special symbols, however this would be ridiculous as a lot of sentences have a plethora of these kinds of characters. 1 2 3 4 5 6 Test 6: Wrapping letters around the alphabet. The final test in development will prove the most difficult. At the moment, when you encrypt the letter W with an offset of 5, for example, you end up with a big problem. ` 1 2 3 4 5 This is a problem, as the task requires that the alphabet wraps around itself. Uppercase letters must stay uppercase letters and lowercase letters must stay lowercase. This code may seem quite complicated at a first glance, but I will now explain how it works. Page 8 Joshua Hadabora 2104 The first four variables are not meant to be changed, similar to constants. These variables are purely to make the code easier to read and easier for me to program with. Without them, I’d have to get the specific character codes for ‘A’, ‘a’, ‘Z’ and ‘z’, which would be quite confusing for anybody to look at as they wouldn’t know why that number was used. Next, charnum is the character code for the character the user entered. charnum2 is the character code but modified with an offset of 5. Finally, this block of code is the most important. It checks if the letter has gone outside the alphabet during encryption. These if statements will return true if the character was in the alphabet range but strayed away from it during encryption. charnum lastuppercase charnum2 charnum is less than or equal to lastuppercase. charnum2 is greater than lastuppercase. Therefore the if statement returns true. 1 2 3 4 5 When one of the if statements return true, all we do is simply takeaway the amount of letters in the alphabet from the character code. So the ‘\’ character from the example above has a character code of 92. When we take away 26 from it, we get 66. Converting 66 to a character gives us the capital letter B. This test and the previous test has fixed the bugs in test number 4, which means that we can now create the actual program and then test our final solution to see if it all works. Page 9 Joshua Hadabora 2104 Final Solution This is the final solution for a Caesar Cipher program, written in Python. The code is even heavily commented so it is all explained. Test 1: Does an error appear when an offset that’s not in range is entered? This test will check to see if the user entered an offset less than -25 or greater than 25, because an offset out of this range could break the program like this: So that’s why we need to use validation to not allow the program to continue if the offset is out of this range. Page 10 Joshua Hadabora 2104 raise Exception terminates the program and tell the user what they have done wrong like this: An advantage of using raise Exception over print is that we get a clear red text message that will let the user definitely know they’ve done something wrong. However, a disadvantage is that the traceback shows up above the error which looks ugly and might confuse users who don’t understand what it means. We could also not validate the offset at all and instead clean up after the user by fixing the offset they have passed to the program. We could apply a modulo operation to the offset to make sure it’s between 25 and -25. This would get the remainder of dividing the offset by 26, which means that if the offset went past 25, it would have 26 subtracted from it. Also, if the offset goes past -25, it will have 26 added to it. 28 2 36 10 -31 -5 86 8 1 2 3 4 Page 11 5 6 Joshua Hadabora 2104 Test 2: Putting in the alphabet in uppercase with an offset of 3 to test encryption. Now we will test the actual encryption part of the program by entering the entire alphabet (to make sure each letter encrypts correctly) and using an arbitrary offset of 3. As you can see, every letter shifted correctly – even the letters that would break (X, Y and Z) without the wrapping created in the development test 6 worked correctly. 1 2 3 4 5 6 Test 3: Decrypting the encrypted alphabet. Although a method for decryption isn’t required, it is still a thing that most people would want. If we couldn’t decrypt an encrypted message, what would be the point of encrypting it? Besides, decryption was easy enough to create – only needing about two more lines of code in exchange for a whole new functionality to the program. By entering a negative number, a user can easily decrypt an encrypted message that could’ve been from the same program or given to them from an outside source. 1 2 3 4 5 6 Test 4: Putting in a lowercase alphabet with a different offset of 12. All of the tests with the uppercase alphabet have passed so far, and the lowercase alphabet is no exception, even though it is positioned away from the uppercase alphabet on the ASCII table. Page 12 Joshua Hadabora 2104 As shown by the screenshot, the lowercase alphabet performs no differently to how the uppercase alphabet would. 1 2 3 4 5 6 Test 5: Encrypting a full sentence. Practically, nobody is going to want to encrypt the alphabet all the time. Now we will test to see if a full sentence will encrypt without fail. The sentence will be “The quick brown fox jumped over the lazy dog.” This sentence has a capital letter at the start, a full stop at the end and a plethora of spaces with the addition of having every single letter of the alphabet included. This will test if the special characters and spaces make the program crack. The program flawlessly passes the test. It keeps the capital letter at the start of the sentence a capital letter, correctly shifts all of the letters and perfectly deals with spaces and the full stop at the end. 1 2 3 4 5 6 Test 6: Decrypting the encrypted full sentence. This final test is just to make sure the program works correctly and is capable of decrypted a full sentence it originally encrypted. We’re expecting “The quick brown fox jumped over the lazy dog.” The final solution had no errors I could see, and passed all the tests successfully. 1 2 3 4 Page 13 5 6 Joshua Hadabora 2104 Recap To recap, here are all the tests that were performed in a final table. Development Tests Test No. 1 2 3 4 Test Using the input function to get a string from the user. Using a for loop and the range function to iterate through every letter of a string. Getting the ASCII code of a character. Inputs “Computer Science” Expected Outcome “Computer Science” as an output. Actual Outcome “Computer Science” as an output. “Computer Science” “Letter 0: C”, “Letter 1: o”, “Letter 2: m”, etc. “Letter 0: C”, “Letter 1: o”, “Letter 2: m”, etc. “Computer Science” A comma separated list of ASCII character codes. Changing a letter with an offset of 3. “b” “y” “;” ““ “e” “b” “;” “” A comma separated list of ASCII character codes: 67,111,109,112, 117,116,101, etc. “e” “|” “>” “#” Fixed By: Tests 5 and 6 “d” Denied encryption of the semi colon. 5 Passed? Disallowing “a” “d” encryption of “;” Deny encryption of numbers, the semi colon. spaces and special characters. 6 Wrapping “y” “b” “b” letters around the alphabet. Development of this program was not challenging, although there was some problems that needed to be overcome on the way. The big one here being letters turning into special characters because the letters don’t go back to a. Page 14 Joshua Hadabora 2104 Final Solution Tests Test No. 1 2 3 4 5 6 Test Does an error appear when an offset that’s not in range is entered? Putting in the alphabet in uppercase with an offset of 3 to test encryption. Decrypting the encrypted alphabet. Putting in a lowercase alphabet with a different offset of 12. Encrypting a full sentence. Decrypting the encrypted full sentence. Inputs Offset of 34. Expected Outcome Exception: Your offset needs to be greater than -26 and less than 26. Actual Outcome Traceback … Exception: Your offset needs to be greater than -26 and less than 26. “ABCDEFGHIJK LMNOPQRSTU VWXYZ” with an offset of 3. “DEFGHIJKLMNOPQ “DEFGHIJKLMNOP RSTUVWXYZABC” QRSTUVWXYZABC” “DEFGHIJKLM NOPQRSTUVW XYZ” with an offset of -3. “abcdefghij klmnopqrstuv wxyz” with an offset of 12. “ABCDEFGHIJKLMN OPQRSTUVWXYZ” “ABCDEFGHIJKLMN OPQRSTUVWXYZ” “mnoprqstuvwxyza bcdefghijkl” “mnoprqstuvwxyza bcdefghijkl” “The quick brown fox jumps over the lazy dog.” with an offset of 16. Encrypted sentence with spaces and full stop intact. “Jxu gkysa rhemd ven zkcfi eluh jxu bqpo tew.” with an offset of -16. “The quick brown fox jumps over the lazy dog.” Encrypted sentence with spaces and full stop intact. “Jxu gkysa rhemd ven zkcfi eluh jxu bqpo tew.” “The quick brown fox jumps over the lazy dog.” Passed? Evaluation Meeting Requirements The program has been designed to fulfil the task requirements as well as test my skills in developing features that I felt were essential e.g. validation and decryption. Screenshots were created throughout the extensive testing to provide evidence that the program works as intended. All these tests, roughly based on the requirements, eventually passed. On the next page is a table to show every requirement and the tests that fulfilled it. Page 15 Joshua Hadabora 2104 Requirement Tests The string can include special characters like Development, Test 5. numbers and symbols, but these will not be encrypted and will stay the same throughout the process of encryption. Uppercase letter will remain uppercase and Development, Test 6. lowercase will remain lowercase. (The alphabet must wrap around itself.) An error must be thrown if the offset is less Final Solution, Test 1. than -25 or greater than 25. (These numbers are chosen because they are the range of the alphabet.) The encrypted string will be displayed after Final Solution, Test 2. this process. The obvious requirements such as the string not being able to be blank and the offset needing to be an integer have not been tested, but are in the code. The code above throws an exception if the string is blank, breaking the program. This code throws an error if the string can’t be converted to an integer. This is right from Python and no user intervention was needed here. Concepts Brute Force Brute force is a concept that could easily be put in this program. Brute force decrypts a string using all 25 possible offsets. Here is a quick draft to prove this concept: Page 16 Joshua Hadabora 2104 The code for this program is not polished, but it definitely works. If something was encrypted using the Caesar Cipher, this program could give the user a list of possible solutions which they could make their best judgement with. I’ve decrypted the string ‘Computer Science’ with an offset of 7, but if you didn’t know the offset it would take trial and error to be able to decrypt it with the standard Caesar Cipher program. The string Computer Science is shown at the 19th offset. Conclusion In conclusion, this report has proved that this program has met all the requirements made by the task, even throwing in extra such as decryption and validation. Page 17