Dt Encryptor User Manual
Posted : admin On 30.01.2020EncryptorHave you ever wanted to send a secret message? The PlanToday we use computers to mask messages every day. When you connect to a website that uses 'https' in the address, it is running a special encoding on your transmissions that makes it very difficult for anyone to listen in between you and the server.The science of masking and unmasking data is called cryptography.
When you take readable data and mask it, we say that you’re 'encrypting' the data. When you turn it back into readable text, you’re 'decrypting' the data.Let’s build a tool named 'Encryptor' that can take in our messages, encrypt them for transmission, then decrypt messages we get from others. Encryption AlgorithmsAn algorithm is a series of steps used to create an outcome.
For instance, a recipe is a kind of algorithm – you follow steps and, hopefully, create some food.There are many algorithms used in cryptography. One of the easiest goes back to the days of Ancient Rome.Julius Caesar needed to send written instructions from his base in Rome to his soldiers thousands of miles away.
What if the messenger was captured or killed? The enemy could read his plans!Caesar’s army used an algorithm called 'ROT-13'. Building a Cipher'ROT-13' is an algorithm that uses a cipher. A cipher is a tool which translates one piece of data to another. If you’ve ever used a 'decoder ring', that’s a cipher.
The cipher has an input and an output.Let’s make a cipher for 'ROT-13':. Take a piece of lined paper.
In a column, write the letters A through Z in order down the left side. On the first line, start a second column by writing the letter N next to your A. Continue down the alphabet, so you now write 'O' to the right of 'B'. When your second column gets to 'Z', start over again with 'A'The left side of your cipher is the input, the right side is the output. Using the CipherYou take each letter of your secret data, find it in the left column, and write down the letter on the right.
Now you have an encrypted message.To decrypt a secret message, find the letter on the right side and write down the letter on the left. Exercises. What is the result when you encrypt the phrase 'Hello, World'?. What is the decrypted version of a message 'anqn'?Starting Encryptor The Big PictureWe need an object which will perform the encryption and decryption operations.
We will define a class then write methods in that class. From IRB we can load that class, create an instance of it, then tell it to do the work with our messages. Setting up the ClassWe’ll create a class which does both the encrypting and decrypting. Let’s start it off like this.
2.1.1:001e = Encryptor.new = #The second line there is the output you’ll see in IRB. The numbers/letters at the end will be different. Writing an encrypt MethodWe made a class, that’s a start – but it doesn’t do anything!We need to write an encrypt method. The Simplest Thing That Could WorkIn computer programming, you want to first do the simplest thing that could possibly work.
Often this is a solution that’s difficult to maintain as requirements change or somehow 'cheating.' But the idea is that you get it working first, then you make it better.Let’s build a really simple implementation of encrypt using a lookup cipher like you made on paper. Lookup TablesWhen you created the cipher on paper you made what’s called a 'lookup table'. It’s a tool which you use by having some value, finding it in the list, and getting out some related value.For instance, when the input to your lookup table is 'A', then the output is 'N'. Let’s build a lookup table in Ruby.The easiest way to build a lookup table is to use a Ruby hash.
A Quick Reminder about HashesIf you recall, a hash is a collection of key-value pairs. When you want to find data in a hash, you give it the key and it gives you back the matching value.Try this in IRB. 2.1.1:001e.encrypt('M')Did you get back nil? Remember that nil means 'nothing' in Ruby. Our encrypt method is looking in the cipher for a key 'M', but it isn’t finding it. As far as Ruby is concerned, 'M' and 'm' are totally different things.What should we do? Add all the capital letters to our cipher?
That’ll take us another 10 minutes!!! A Hack to Deal with Uppercase/LowercaseLet’s implement a hack (or a 'cheat') and say that no matter whether the incoming letter is uppercase or lowercase, we’re going to output lowercase. Spies who are using our advanced cryptography system can fix the letters to uppercase on their own!What we’ll do here is modify the encrypt method so it turns every input into lowercase before looking it up in the cipher. If you pass in 'a' it will just stay as 'a' and be found in the cipher. If you pass in 'A' it will be changed to 'a' and found in the cipher.Let’s change our encrypt method to use the.downcase method. This method turns any string into all lowercase letters.
2.1.1:001e.encrypt('Hello')What did you get? There’s no magic in programming. We’ll need to write more instructions. A TheoryI know, let’s just make a lookup table that has all the words in the English language and points to their encrypted version! Come back in 20 years when you’re done typing that up.Instead, let’s encrypt one letter at a time. The algorithm will go like this:.
Cut the input string into letters. Encrypt those letters one at a time, gathering the results. Join the results back together in one stringLet’s do it! Remember.split?We looked at the.split method on Strings before.
It can cut up strings like this. 1letters = string. Split ( ' )Now we’ve got an Array of letters. Encrypt Those LettersThis is the tricky part. Let me show you the simplest way first, then the best way second.
Gathering Results with an ArrayImagine you had a bunch of math problems to solve and needed to turn in a list of the solution. What would you do?Probably grab a piece of paper, do the problems one by one, and write down each answer on the paper as you finish the calculation. Right?We can do that in Ruby, too. Let’s experiment in IRB. 1 2 3 4 5 6 7 8 9 10 11 12 13def encrypt ( string ) # 1. Cut the input string into letters letters = string. Split ( ' ) # 2.
Encrypt those letters one at a time, gathering the results results = letters. Each do letter encryptedletter = encryptletter ( letter ) results. Push ( encryptedletter ) end # 3. Join the results back together in one string endJoining the Resultsresults holds an array of letters, but we want to finish with a single string. Remember how to mash all the elements of an array together into a string?We need the.join method. Call.join on the results array as the last line of.encrypt. TestingTry this in IRB.
2.1.1:001 2.1.1:002 2.1.1:003load './encryptor.rb' = true e = Encryptor.new = # e.encrypt('Hello') = 'uryyb'Did yours work? If you didn’t get the exact same output 'uryyb' go back and figure out what’s going wrong. RefactoringWhenever we program we want to do the simplest thing that could possibly work. But then once it works, we try to make the code better. We can make it better by making it shorter, easier to understand, or faster to run.This process is called refactoring.My encrypt method currently looks like this. 1 2 3 4 5 6 7 8 9 10 11def encrypt ( string ) letters = string.
Split ( ' ) results = letters. Each do letter encryptedletter = encryptletter ( letter ) results. Push ( encryptedletter ) end results. Join endThe.collect methodThe next piece I’m interested in is the middle section. Arrays in Ruby have a method named.collect.The.each method that we’re already using goes through the elements in the array and runs the block once for each element.The.collect method does the same thing, but it also gathers the results of running the block into an array and gives you back that array.Let’s try an example in IRB.
2.1.1:001 2.1.1:002 2.1.1:003 2.1.1:004 2.1.1:005 2.1.1:006 2.1.1:007sample = 'a', 'b', 'c' = 'a', 'b', 'c' sample.each do letter letter.upcase end = 'a', 'b', 'c' sample.collect do letter letter.upcase end = 'A', 'B', 'C'Do you see the difference in the outputs? When we use.each, we get back the original sample lettters.
It’s as though the.upcase never happened.When we use.collect though, we get back the three letters capitalized. This array is the result of running the.upcase method and gathering the results.To take it a step further, we could save the capitalized letters into a new array like this. 2.1.1:001 2.1.1:002 2.1.1:003 2.1.1:004capitals = sample.collect do letter letter.upcase end = 'A', 'B', 'C' capitals = 'A', 'B', 'C'Now we have an array named capitals which holds the same results. Challenge: Using.collect in.encryptNow look at your code for encrypt. How can you use.collect instead of.each and get rid of two lines of code?Make sure that your encrypt method still works by testing it in IRB after you make the changes. DecryptingEncrypting is cool, but only if you can eventually decrypt the message.There’s this funny thing about decrypting ROT-13.
There are 26 letters in the alphabet. Moving forward 13 letters is the same as moving backward 13 letters.Write your own ’.decrypt’ method so that when tested you get output like this. 2.1.1:001 2.1.1:002 2.1.1:003load './encryptor.rb' = true e.encrypt('Secrets') = 'frpergf' e.decrypt('frpergf') = 'secrets'Now you have a proper encryption/decryption tool. Supporting More CiphersWhat if the enemy figures out the cipher?We could change the cipher at any time. For instance, we could decide to use a 'ROT-8' and only rotate eight letters.How would you do this given the current implementation?
You’d have to retype the entire cipher - yuk.Worse, what if you want your one encryption engine to support both ROT-13 and ROT-8? What about ROT-4? You might need to write 26 different ciphers.That’s ridiculous. Instead, let’s figure out how to do our encryption and decryption automatically allowing us to get rid of the original cipher all together.
RangesRuby has the ability to specify ranges of letters and numbers. Ranges specify a starting letter or number and a finishing letter or number. Ranges are a shorthand way of stating you want all the values in between the start position and the end position.
2.1.1:001 2.1.1:0021.9 = 1.9 (1.9).toa = 1, 2, 3, 4, 5, 6, 7, 8, 9A range is similar to an Array and can stand in for an array if you convert the range to an array with the toa method. The first example shows the range we described. In the second example we convert the range into an array. This will show us every value in between.Two of our ranges represented characters in the alphabet. We wanted a range of all the lower case letters and a separate range of all the upper case letters. We can also define a range which is both the upper case and the lower case letters.
2.1.1:001 2.1.1:002'A'.' Z').toa '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', ', ', ', '^', ', '`', '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'We define a range from an upper case ‘A’ to a lower case ‘z’.
That seemed to work correctly. When we converted to an array it seems to have included a bunch of extra characters. Why did that happen?All of the characters you can possibly type are stored somewhere in a big, long list. What we are seeing above is a subset of that big list. Someone decided awhile ago to store a few extra characters between the upper case letters and the lower case letters.We can see an even bigger list if we create a range between the space character ’ ’ and a lower case ‘z’.
2.1.1:001 2.1.1:002' '.' Z').toa ' ', '!' , ', '#', '$', '%', '&', ', '(', ')', '.' , '+', ',', '-', '.'
, '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', ', '?' , '@', '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', ', ', ', '^', ', '`', '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'Wow. That is a long list of characters. The best part about the list is that it contains nearly all the possible characters we could write in a message. This is something that we can use to our advantage when creating our cipher.
This will save us many keystrokes by using Ranges that we convert to Arrays. 1 2 3 4 5 6 7characters = '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' rotatedcharacters = 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm' characters. Zip ( rotatedcharacters ) # 'a', 'n', 'b', 'o', 'c', 'p', 'd', 'q', 'e', 'r', 'f', 's', 'g', 't', 'h', 'u', # 'i', 'v', 'j', 'w', 'k', 'x', 'l', 'y', 'm', 'z', 'n', 'a', 'o', 'b', 'p', 'c', # 'q', 'd', 'r', 'e', 's', 'f', 't', 'g', 'u', 'h', 'v', 'i', 'w', 'j', 'x', 'k', # 'y', 'l', 'z', 'm'The reason that we zipped the two arrays together is because Hash has a special creation syntax where if you provide with pairs it will create keys and values from it.
The four lines of code that you just wrote is equivalent to all the time and energy you spent building your first cipher.From this point forward we will use the character range ' '.' This will give us all upper case letters, numbers, lower case letters, and a bunch of common punctuation symbols. 2.1.1:001 2.1.1:002e.encrypt('Hello', 13) = 'Uryy!' E.encrypt('Hello World', 13) = 'Uryy!-d!$yq'Wow. That is great. No one will know what we are saying to each other!
Writing decryptSpeaking of which, we need to rework our decrypt method.Depending on how you wrote the method originally, this might be easy or it might be hard. Consider this:Decrypting is the opposite of encrypting.
In our current process encrypting means moving forward rotation number of spots in the character map. Decrypting is then moving backwards the same number of spots.Implement your own version of decrypt that can successfully match these results. 2.1.1:001 2.1.1:002 2.1.1:003 2.1.1:004 2.1.1:005 2.1.1:006load './encryptor.rb' = true e = Encryptor.new = # encrypted = e.encrypt('Hello, World!'
, 10) = 'Rovvy6.ay!vn+' e.decrypt(encrypted, 10) = 'Hello, World!' Encrypted = e.encrypt('Hello, World!' , 16) = 'Xu!!$ 'Hello, World!' Now our encryption engine can flexibly use any rotation number! Working with FilesYour encryption engine is cool for encrypting a few words, but what about a whole file?
Using what we’ve already built, it’s not too hard. Experimenting with File I/OLet’s first play with 'File I/O' in IRB. When we say 'I/O' we mean 'Input / Output'.We’ll load a plain message in as input, then encrypt it, and output a new file with the encrypted message. We could then transmit that encrypted file, maybe as an email attachment, then our trusted correspondent can decrypt it back to a plain file.File I/O in Ruby is much easier than many other programming languages. Let’s do I/O backwards and output a file first. File HandlesWhenever we work with files we create a file handle. You can think of this as a connection between the program and the file system which holds the files.It wouldn’t be accurate to say that a program holds or contains a file.
Instead, we have this connection to the file system and can ask that connection to read in data from the file or write data out to it. Outputting to a FileLet’s start by outputting some text to a file. Try this in IRB. 2.1.1:001 2.1.1:002 2.1.1:003 2.1.1:004out = File.open('sample.txt', 'w') out.write('Hello, World!' ) out.write('This is a file, hooray.' ) out.closeWhen you run that then change back to SublimeText, you may see the sample.txt file pop up on the left side. If not, go to the FILE menu, click OPEN, and find sample.txtWhat do you notice about this file?
There’s something that isn’t quite right about how it writes out the text – the two lines of text are on the same line of the output file.Try the instructions above, but add a n to the end of the strings that you write out. This is a special marker to create a 'new line'. Reading a FileThe first line of the previous example was this.
ReadWhat do you get out? Is that what you expected?Probably not. When you open a file for reading you start with a 'cursor'.Imagine you had a piece of paper with words on it. When you first look at the paper, you could put your finger on the first word on the page. This is your cursor.If someone told you to read the page, you’d move the cursor along word by word, line by line, until you got to the end.
When the cursor was on the last word, you’d stop.File handles work the same way. When we first opened the file the cursor was on the first letter of the file.
When we said.read it read back all the contents of the file.But then the cursor was at the end of the file. If we call.read again we’ll just get back nil because there’s nothing left in the file.If you wanted to read the file from the beginning again, you could do this. 1 2 3def encryptfile ( filename, rotation ) endThis method will take in two parameters, the filename of the file to be encrypted and the number of letters to rotate. PseudocodeAdd this pseudocode into the method as comments:. Create the file handle to the input file. Read the text of the input file.
Encrypt the text. Create a name for the output file.
Create an output file handle. Write out the text. Close the fileImplement ItYou’ve seen all the components that you need here. Figure out how to implement this method on your own. Here are a few notes to help you:. Use the filename variable from the parameter with the File.open call.
Remember to specify the right read/write mode. Just call the same method you did before to read the contents. You’ll need to save this into a variable. Call your.encrypt method passing in the text from step 2 and the rotation parameter. Name the output file the same as the input file, but with '.encrypted' on the end. So an input file named 'sample.txt' would generate a file named 'sample.txt.encrypted'. Store the name in a variable.
Encryptor Download
Create a new file handle with the name from step 4 and remember the correct read/write mode. Use the.write method like before. Call.close on the output file handleTest ItRun your code from IRB. 2.1.1:001 2.1.1:002 2.1.1:003load './encryptor.rb' = true e = Encryptor.new = # e.encryptfile('sample.txt', 5) = nilYou get back nil because the.close method you called on the output file returns nil.Open the sample.txt.encrypted in SublimeText. Does it look like a bunch of junk? Hopefully so!
No one is going to be able to read your secret message. Writing a decryptfile MethodBut did it really work? We can’t know until we write a decryptfile method.
Method SignatureThe method should look like this. 1 2 3def decryptfile ( filename, rotation ) endPseudocodeThe pseudocode is almost the same:.
Create the file handle to the encrypted file. Read the encrypted text. Decrypt the text by passing in the text and rotation.
Create a name for the decrypted file. Create an output file handle. Write out the text. Close the fileYou know how to do most of this.
Here are two tricky parts: Step 1. Read File HandleFor the very first step, where you create the file handle, Ruby will fail to detect which language the file is written in because of all the strange characters. You need to put a little more information in the read/write mode declaration like this.
1'f w)0/6X0// -6C6` '46j$( 'You know that the message is using a rotation encryption scheme (the person that sent it finished the same tutorial as you). However, what you do not know is the rotational number. What rotation number are they using? Finding which rotationTo understand the encrypted message you need to figure out the rotation number they used. Knowing that number will allow you to change your decryption tools to get the original message. How do you find the rotation?
Ask the writer or receiver of the message to tell you what rotational number they are using.Ask the writer or receiver of the message to tell you what rotational number they are using. Decrypt the message and look at the output and see if the message looks correct.The solution involves very little programming.
It instead relies on your ability to get people to give you information. Surprisingly people will volunteer this information. Especially if you are able to convince them you are on their team. Of course, the person telling you the rotation value may not be telling the truth. Guess a rotational number based on something you may know about the writer or receiver of the message.Guess a rotational number based on something you may know about the writer or receiver of the message. Decrypt the message and Look at the output and see if the message looks correct.This solution involves you trying to understand what number a person might choose. Does the writer of this use the same rotational value when sending you encrypted messages?
Does the writer or receiver have a favorite number? Finding the solution requires you to make a guess, change your decryption code, run it, and then review the message.Like a game of hangman, the number of possible choices grows smaller with each choice. However, making several wrong guesses can be time consuming. Decrypt the message using every rotational number. Looking at all the output and see which message looks correct.Decrypt the message using every rotational number. Looking at all the output and see which message looks correct.This solution is the one that we can best solve with code. Our current decryption method allows us to specify a single rotational number.
We need to create a new method that will generate all possible outputs for all possible rotational numbers. Solving this problem using decryptWe can solve this problem by using our existing decrypt method. We can call it for every possible rotational number. Looking at the results each time. 2.1.1:001 2.1.1:002 2.1.1:003 2.1.1:004 2.1.1:005 2.1.1:006load './encryptor.rb' e = Encryptor.new e.decrypt('f w)0/6X0// -6C6` '46j$( ',1) = 'ezv(/.5W/.z,5B5z&&35i#'z' e.decrypt('f w)0/6X0// -6C6` '46j$( ',2) = 'dyu'.-4V.-y+4A4^y%%24h'&y' e.decrypt('f w)0/6X0// -6C6` '46j$( ',3) = 'cxt&-,3U-,x.3@3x$$13g!%x' e.decrypt('f w)0/6X0// -6C6` '46j$( ',4) = 'bws%,+2T,w)2?2w##02f $w'Trying to crack the encrypted this way is very tedious.
We would need to keep doing this until we found the right one. This could result in a lot of attempts. More importantly, if we wanted to crack another message in the future we would have to do this again.
Instruction Manual
This is another situation where we can use looping to simplify our job. 2.1.1:001 2.1.1:002 2.1.1:003 2.1.1:004 2.1.1:005load './encryptor.rb' e = Encryptor.new (' '.' Z').toa.size.times do attempt puts e.decrypt('ENCRYPTED',attempt) endTo figure out all the possible combinations we need to consider all the possible characters. That is why we needed to use the same range of characters again and figure out how many of them we support. The decrypted message should appear in a list alongside 90 other garbled messages. Take your time to find the message.Congratulations you have cracked the code!
Step 2: Define a method named crack which accepts our encrypted message.We cracked the code. You have intercepted a new message. It is time to crack this one. Times do attempt puts e. Decrypt ( 'ENCRYPTED', attempt ) endHowever, writing that out every single time would be tedious and time-consuming. We should instead make it a standard part of our Encryptor class.
That way we can call it again when we have new messages in the future to crack.Let’s add a new crack method to our Encryptor. The crack method should accept an encrypted message. However, we want to change it slightly. Instead of outputting the messages immediately with the puts method we want to collect them all and send return them. This will allow us to save them to a file if needed. Further Exercise Real-Time EncryptionYou want to start using your encryption in more of your communication.
Writing your original message to a file, encrypting it, and opening the file requires a lot of effort. It is not well suited for small amounts of text like a chat message or text messages.Create a system that will allow you to type a unencrypted message and have the encrypted version appear.Create a system that will allow you to type an encrypted message and have the unencrypted message appearPassword Protecting Your EncryptorThe encryptor program does a fair job at protecting your correspondence. The messages you send to and from your friends are safe from prying eyes. However, your security would be compromised if your encryptor code fell into the wrong hands.Add a simple password prompt when running encryptor.Protect your simple password by using your encryption.Use Ruby’s MD5 Hash of the password and store that in the file.Use Ruby’s MD5 Hash to compare incoming password attempts to see if they matchBuilding Better a ROTWe saw how easy it was to break the encryption when we used a single rotation value. We could build better encryption if we used multiple rotations within the same document. Pick three different numbersSelect three numbers that you can remember. These three numbers will be the three encryption rotations that we will cycle through as we encrypt each letter.
Dt Encryptor User Manual Software
When encrypting each character, continue to cycle through the three numbers you selected as your encryption ROT value.Encrypting each letter with a different rotation will make it hard for for someone to crack your messages. Even if they were able to figure out that you were using three different rotations they would still need to generate all possible outputs to see which one looked correct.Assuming you are rotating through the same 91 characters, choosing three numbers would require a cracker to look through 753571 possible combinations to figure out what you wrote. Each number you add would make that amount increase even more!