|
|
|
In the previous two documents, All About Our Encryption Algorithm and All About Our Decryption Algorithm, we learned about the algorithm we use to encrypt and decrypt text. However, in real life there are often complications caused by limitations in the tools available. Our project is no exception. In order to make our application simple, we will be using common components to display the text and common streams to read and write the text to and from a file. Since I've decided to stick to "character" streams, some constraints are placed upon us. For example, some characters cannot be written or read from a "character" stream. Since we do not know, ahead of time, what characters will be created by the encryption algorithm, we must assume that some of them cannot be written to a character without problems. As well, we must assume that some cannot be read from a character stream without problems. Additionally, the text box control that we will use to display text expects characters within a certain limit (specifically, the characters found in a text file). We need to make sure that we never try to display characters that text box cannot handle. Likewise, we need to make sure that we do not read or write characters to a character stream that a character stream cannot handle. All of this is easy to address if we make some design decisions now. We will make sure that all characters, when encrypted, result in characters that are within the normal range of readable and writable characters. We will do this by adding an additional layer to our encryption algorithm and an additional layer to our decryption algorithm. EncryptionThe ConceptFor encryption, rather than storing the result of a character encryption as a single character, we will translate the result into a string of digits representing, in decimal, the character code encrypted character. For example, in the document All About Our Encryption Algorithm, we showed that if one encrypts the character 'W' by XOR'ing it with "X", we get the binary number 00001111 as a result. That is, 'X' XOR 'W' = 01011000 XOR 01010111 = 00001111 Now, we never see the binary number directly. From our point of view, a number is a number. While the number is encoded internally as 00001111, if we were to translate it to a string using CStr, CStr would return the string "15", which is decimal for 00001111. Thus, we would encrypt 'W' using the key 'X' as the string "15". In order to distinguish were one encoded character, represented by a string of digits, begins and ends, we will separate them with a space character. Thus, given some input text, the encrypted text will be a sequence of decimal integers, each corresponding to an encrypted character of the original text, separated by spaces. For example, if we were to encrypt the text "ANT" using the key "XYZ", the encrypted text would be "25 23 14", where "25" represents the encrypted value of "A", "23" represents the encrypted value of "N" and "14" represents the encrypted value of "T". Written mathematically:
Our editor will need to be able to distinguish between encrypted text and clear text (clear text is non-encrypted text (or decrypted text)). We will adopt the following convention. All encrypted text will start with the character sequence "#BEGIN ENCRYPTED " and end with the character sequence "#END ENCRYPTED". The double quotes are not included in the character sequence. The last character in "#BEGIN ENCRYPTED " is a space. The last character in "#END ENCRYPTED" is the letter 'D' (We add a space to the end of "#BEGIN ENCRYPTED " because we wish to separate it, using a space, from the first encrypted character code in the text. We do not add a space before "#END ENCRYPTED" because our algorithm (specified in pseudo code below) will place a space after each encrypted character, thereby leaving one before "#END ENCRYPTED".). Therefore, using the example above, if we were to encode the text "ANT" using the key "XYZ", the encrypted text would be: "#BEGIN ENCRYPTED 25 23 14 #END ENCRYPTED" Pseudo CodeWhile reading the following, keep in mind that in the encryption code, we are converting directly from a clear text string to an encrypted string. String indices begin at 1. Therefore, the first index of a string is 1 and the last is the length of the string. This effects some of our calculations below.
DecryptionThe ConceptWhen we decrypt encrypted text, we transform the encrypted text back to clear text. Stated in other words, we reverse the encryption process. The first step in revering our encryption process is to remove the characters "#BEGIN ENCRYPTED " from the start of the encrypted text and remove the characters "#END ENCRYPTED" from the end of the encrypted text. After we remove "#BEGIN ENCRYPTED " and "#END ENCRYPTED", what we have left is a sequence character codes expressed in decimal. For example, given "#BEGIN ENCRYPTED 25 23 14 #END ENCRYPTED" we now have "25 23 14 ". The next step is to transform string " 25 23 14 " to the array {"25", "23", "14"}. We can perform this task using Visual Basic's Split function. To decrypt the text, we translate each of the character codes, expressed now as a string, to integers. Each of these integers is represented internally as a binary number. Since they are binary numbers, we can perform the XOR operation on them. For each element in the array mentioned above, convert it to an integer using CInt and then XOR the integer with the character code of the corresponding key character. The result will be the character code of the decrypted character. We then translate this character code to a character and append it to the end of a string. At the end, the string contains the original clear text. Let's take a closer look. The string "#BEGIN ENCRYPTED 25 23 14 #END ENCRYPTED" is stripped of "#BEGIN ENCRYPTED " and "#END ENCRYPTED" resulting in " 25 23 14 ". We next translate the string " 25 23 14 " to the array {" 25", " 23", " 14"} using Split. Next, for each element in the array, we translate it into its integer value using CInt and then XOR it with the character code of the corresponding character in the key. For example, if our key is "XYZ" then the character codes, in base 10, are 88, 89 and 90. Retrieving the original text, therefore, requires doing the following:
Pseudo CodeWhile reading the following, keep in mind that in the encryption code, we are converting indirectly from an encrypted string to a decrypted string. The conversion is indirect because we convert first, from a string to an array and then from an array to a string. String indices begin at 1. Array indices begin at 0. Therefore, the first index of a string is 1 and the last is the length of the string. The first index of an array is 0 and the last index is length - 1. This effects some of our calculations below.
|