Tuesday, February 19, 2013

Living my LiveCode Dream: Encryption

As I wrote recently, I had a little dream of creating I've a little encryption app that would store one's usernames and passwords, but with the option to "encrypt" them a little bit as a way to disguise the full information. I find myself constantly forgetting which username and password go together for all of the various accounts I have. Even though there appears to be no need for this app (given how many free apps are already out there that do this sort of thing), I thought it still would be a good little project to explore.

First, an all important disclaimer. This program does not, in fact, do any encryption in the technical sense. "Disguise" would probably be a better word. That is because the "identity" of the password is contained in one variable in its raw (unencrypted) state, while another variable is used to reveal its identity. OK, enough already, on with the show.

So, here is my first attempt with a file called "lloydencryption1.livecode." Here is a screen shot of the first card:

As I hope you can surmise, you enter a word in the target field, then press the "encrypt" button to encrypt the word by changing every non-capital letter and non-number into an asterisk.

All of the code is found in the "encrypt" button:

on mouseUp
   put empty into varWordEncrypt
   put line 1 of field "target" into varWord
   put the length of varWord into varLength
   repeat with varChar = 1 to varLength
      //Only show capital letters and numbers:
      if (charToNum(char varChar of varWord) >64 and \
      charToNum(char varChar of varWord) <91) or \
      (charToNum(char varChar of varWord) >47 and \
      charToNum(char varChar of varWord) <58)
         put varWordEncrypt & char varChar of varWord into varWordEncrypt
         put varWordEncrypt & "*" into varWordEncrypt
      end if
   end repeat
   put varWordEncrypt into line 1 of field "result"
end mouseUp

First, note that the symbol \ simply allows for a very long line of code to be broken into separate lines. But, let's start at the top and work our way down.

Line 1: on mouseUp
Line 2: After pressing the button, the first line clears out any contents that might have been in the variable "varWordEncrypt."
Line 3: The contents of the field "target" are put into a local variable "varWord."
Line 4 determines the length of the target word, which is very important because the very next line depends on this number to determine the total number of loops to repeat.
Line 5 triggers a loop that repeats for the number of characters in the word.

Now, the next bunch of lines depends on something called ASCII code. Every character on the keyboard has an associated ASCII code.  For example, a lower case "a" has the ASCII code of 97 whereas an upper case "A" has the ASCII code of 65. The numbers 0-9 have ASCII codes ranging from 48-57. How can you determine the ASCII code for a character? You could either consult a Web page with the information, such as http://www.ascii-code.com/ or, if you are really geeky, you could create your own converter (which I actually did -- it's card 2 of the stack). (Note: Apparently, ASCII has generally been replaced with Unicode, but that's not too important right now. I just like ASCII, OK?)

Line 7 is the "encryptor" line. It's long and very unelegant, but we'll improve upon this in a later post. For now, let's see what it does. First, notice that line 7 along with lines 8-12 have this construction:

 if (this and that is true) or (this and that is true)
         do this
         do this instead
      end if

Let's add more pseudocode to line 7. It really translates as the following:

 if (the character is an uppercase letter) or (the character is a number)

The function "charToNum" takes a character and returns the ASCII code of it. Now, remember for a moment that the ASCII for a capital "A"is 65 and the ASCII for a capital "Z" is 90 as we dissect the following bit of code:

charToNum(char varChar of varWord)

Notice that the repeat loop begins with 1 and ends with the length of the word. So, if I enter "Lloyd1", the length (held by the variable "varLength" is 6). Repeat loops such as this are really fun and useful. The loop begins by putting the value of 1 into the variable varChar, then increases by 1 at each and every loop until the loop ends. So, at the first pass, the code "charToNum(char varChar of varWord)" translates as "give me the ASCII code of character 1 of the contents of varWord. At loop 2, it gives us the ASCII code of the second character, and so on until the loop ends when we run out of characters.

So, if the ASCII code for the character is greater than 64 (i.e. 65) and less than 91 (i.e. 90), then it must be an uppercase letter. Similarly, if the ASCII code is greater than 47 (i.e. 48) and less than 58 (i.e. 57), then the character must be a number. That's exactly what line 7 is checking. If all of this is true, then line 9 simply adds that character to a string of characters it is building in the variable "varWordEncrypt." (Note that the ampersand & is the concatenation symbol which basically "adds" one string to another.  If Line 7 is false, then line 11 puts an asterisk in place of the character.

Line 13 ends the repeat command, either sending LiveCode back to Line 5 to start the next loop or the loop ends.

Line 14: It's important to remember that this line only is executed after all of the looping concludes. This line takes the result of the looping -- the building, character by character, of the variable "varWordEncrypt" -- and puts into the line 1 of the field target.

(Whew! As always, it's harder to write up an explanation of the code than to actually do the coding!)

Now, you might be asking, what if i wanted to encrypt only lowercase letters, or maybe only the vowels, or only constants, or only prime numbers, etc., etc. One answer would be to keep changing line 7 accordingly. But, that's a pain, plus how about if I want to give the user the option of what to encrypt, including encrypting everything or nothing? Line 7, as it is currently constructed, just won't do.

In one of my next postings, I will share a more elegant way to do this in the context of giving the user the option of what (or what not to) encrypt.

By the way, why am I going to all this trouble when my dream of creating the encryption app is a pipe one. Two reasons. One, it's a lot of fun doing it. If that is not reason enough, then my second is that I see this as a wonderful gaming feature that I could use at some point. Imagine being in a virtual world where you are given an encrypted message and you must go on a quest to unlock the code. It would be cool to slowly see a message emerge as you meet challenges in the world, something like:

And, I'm sure I can think of other good uses of this as well. But, I'm really just doing it because it is fun.

P.S. Go to this stack's second card to find a little "ASCII code generator" that you might find helpful.

No comments:

Post a Comment