Fred Kleinschmidt wrote:The line
is declaring the variable cipherText as a String, and initializing it to an empty string. then later in the do-loop,
keeps appending on to that string, which is eventually returned to the caller.
Justin Robbins wrote:why is cipherText being initialized and declared to an empty string in the first place? what's the logic behind it?
The replaceVar character is being appended to the cipherText string that is going to store the complete solution. This line is equivalent to cipherText = cipherText + replaceVal.
Adam Scheller wrote:I will try to explain you how the encrypt method works.
The method takes two arguments: plainText which is the text that is going to be encrypted, and shiftKey which defines the shift of the letters. In example, plainText set to "C" with shiftKey set to 2 would return "A".
This code converts all letters in the plainText String into lowercase. It's just to simplify the algorithm. Lowercase and uppercase characters are different, so the author of this code decided to work on lowercase characters only.
cipherText is a String where encrypted message is going to be stored. The variable is initialized with an empty string because local variables must be explicitly initialized before first use, otherwise the code wouldn't even compile. Strings aren't automatically initialized to empty strings, you have to do it yourself.
Here beings a loop that repeats itself as many times as there are characters in the plainText String ( plainText.length() ). The code in the loop, which I describe as next, will handle every character from the plainText separately.
charPosition is a position of the current character (from plainText String) in in the alphabet.
ALPHABET is a String containing all letters of the alphabet in order.
ALPHABET.indexOf(...) looks in ALPHABET for a substring provided in the argument and returns it's position.
plainText.charAt(i) returns character that is stored in plainText on position i. The i is the integer that is incremented in the for loop.
Summarizing this line of code, it takes the current character from plainText, finds its position in ALPHABET, and assigns that position into charPosition integer.
keyVal is a number that stores position of encrypted character. (shiftKey + charPosition) shifts the current character position by shiftKey. The modulo 26 on the end is required to avoid a situation where some character is shifter beyond the last position in ALPHABET. With this modulo, any shift beyond the last position will continue from the beginning of ALPHABET. In example, if you will try to shift character "Z" by two, you will get "B" in return.
The replaceVal character contains the encrypted character. ALPHABET.charAt(keyVal) returns the character that is stored at keyVal position.
The replaceVar character is being appended to the cipherText string that is going to store the complete solution. This line is equivalent to cipherText = cipherText + replaceVal.
The loop ended before that line. cipherText now contains the encrypted text and is returned from the method.
I hope I managed to explain this code in an understandable way. I tried to use non-techy language as much as possible (so others please don't point that I didn't use word "index" and so on). If you have any questions, post them here.
Now your mission is to explain to yourself the decrypt method the same way as I did above. Line by line. IMO, the best way to check if you understand something well is to try to explain it to somebody else. If you can explain that easily, then you understand that well!
why is it that when we type "C" for plainText and 2 for shiftKey it returns "A"? I was thinking it would shift everything instead to the right? I don't understand if shift has direction or not? but I was thinking it would shift to the right making it "E"? could you explain how that's working.
Also, is there another way to go about the line:
like if I didn't want to create a String (A-Z) or use the method indexOf() is there another way?
Also, how is it that charPosition is declared as an int but then assigned to what I think is a letter and therefore a char from the ALPHABET String? I thought we couldn't convert like that? And how does indexOf() able to take in an int or char and sift through the ALPHABET string? How exactly does that operation carry out?
All things are lawful, but not all things are profitable.
This whole line here truly confuses me:
All things are lawful, but not all things are profitable.
Knute Snortum wrote:Since it's been a while, I'll jump in here.
why is it that when we type "C" for plainText and 2 for shiftKey it returns "A"? I was thinking it would shift everything instead to the right? I don't understand if shift has direction or not? but I was thinking it would shift to the right making it "E"? could you explain how that's working.
I would think of the shiftKey as shifting left, or subtracting from the ASCII value. Every letter has an ASCII value for capitals and lowercase. A "C" has an ASCII value of 67, so 67 - 2 = 65, which is the ASCII value for "A".
Also, is there another way to go about the line:
like if I didn't want to create a String (A-Z) or use the method indexOf() is there another way?
There is. You could try
This treats the char as an ASCII value.
Also, how is it that charPosition is declared as an int but then assigned to what I think is a letter and therefore a char from the ALPHABET String? I thought we couldn't convert like that? And how does indexOf() able to take in an int or char and sift through the ALPHABET string? How exactly does that operation carry out?
A type char can be treated as an ASCII value or an alphabetic character.
Justin Robbins wrote:Fantastic answer! Thank you so very much for taking the time to write this.
why is it that when we type "C" for plainText and 2 for shiftKey it returns "A"? I was thinking it would shift everything instead to the right? I don't understand if shift has direction or not? but I was thinking it would shift to the right making it "E"? could you explain how that's working.
Also, is there another way to go about the line:
like if I didn't want to create a String (A-Z) or use the method indexOf() is there another way?
Also, how is it that charPosition is declared as an int but then assigned to what I think is a letter and therefore a char from the ALPHABET String? I thought we couldn't convert like that? And how does indexOf() able to take in an int or char and sift through the ALPHABET string? How exactly does that operation carry out?
I'd like to know if I understand this process right. plainText is the String, so then charAt() is a method within that String, so then when we can apply that method with the dot operator which then enables us to be able to grab a letter from the entered String, which is solely dictated by whatever 'i' was incremented it on, at that very moment in the loop cycle. So if the String is "HELLO" then at i=0 it's H at i=1 it's E and so on, because everything starts at 0.
Then outside of that whole operation is another method indexOf() which derived from the String class of the preceding ALPHABET, so when the dot operator is in conjunction there, indexOf() takes whatever is inside its paren's, which would be dictated on what increment moment 'i' is at in the loop then it spits out the concordant letter of the entered String. But if indexOf() is taking in a letter, based on the loop and the entered String and then communicating that back to ALPHABET wouldn't the entire thing evaluate to a single letter in ALPHABET. But how can that be if the line was declared as an int, so it would look like: int charPosition = char;? Doesn't this break the rules?
This whole line here truly confuses me:
I understand that shiftKey represents the number of shifts along the alphabet that the user entered and that charPosition is an int (or it is a char?) position right then in the ALPHABET String. So it takes into account where the letter is at that moment and then the shiftKey number pushes it along the ALPHABET? But I don't understand how adding shiftKey and charPosition actually does any of this. Why adding them? would it look something like this, example: 3+A%26 = C?
Also, the whole idea behind %26 is messing with my head. So we get an int value (I think) from (shiftKey + charPosition); then we do %26 but why? I don't understand why it's %26 at all. Or what exactly % does, I thought that generates a remainder, why the 26? I could really use an example code of what's going on there. And the whole idea of the wrap around of the alphabet is confusing. Like if someone types in 27 how exactly does that make it start from beginning again of the ALPHABET? like if someone types in 27 how does it go from position of 'Z' to 'B'?
And lastly, how does the conversion work exactly here:
I understand somehow it's using charAt method which is derived from the String class of ALPHABET but taking in keyVal into charAt() how does that work? I don't see the mechanics of that operation.
Adam Scheller wrote:
This code does a cast from char to int. There is a special method for extracting code points named codePointAt(). Use it instead of chartAt().
What you meant is (letter + key) % 26, but what really happens is letter + (key % 26). The modulo operator takes precedence over addition operator. You need to use parenthesis in this case. Parenthesis here work the same way as in mathematics. 2+2x2 = 6, (2+2)x2 = 8.
What are you doing here, is creating a new character with code stored in "letter" variable. Assuming that the line with modulo is fixed, your "letter" value will be always between 0 and 25.
Take a look on the ASCII table. The "Dec" column shows code points for letters stored in "Char" column. When you will take a look at entries between 0 and 25 you will see that there are no letters stored. Letters are stored in ranges 65-90 and 97-122. It would be easier for now to use the method with a String containing alphabet than playing with character code points. Wait until your skills get better.
If you want to get your result always as uppercase characters, you can simply use output.toUpperCase() .
One technical note is that char does not operate on ASCII, but on UTF-16. But since ASCII is a subset of UTF-16, you can use ASCII codes for char as well.
Did you see how Paul cut 87% off of his electric heat bill with 82 watts of micro heaters? |