• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Please help me understand the caesar cipher java code

 
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey everybody!

Been learning Java for about 3 weeks give or take now. Really want to understand this Java caesar cipher code:



I could really use your help here. I don't understand what this means:

Is this to say we take the parameter plainText and customize it to store ONLY lowercase letters?


Also, with:



I don't undestand this line at all. I see that it's creating a new String var called cipherText but why? what's the purpose of this line?


Then after the loop all this happens and I have no understanding of it. I see things are being declared and assigned but I do not understand what the assignments mean:



I did understand how the for loop worked and how it starts at 0 then checks the condition and runs through the block and updates 'i' to be +1 more, then it restarts until the condition is no longer true. I feel like if someone could break down the mechanics of this code the rest I would have no problem with.

Thank you
 
Bartender
Posts: 732
10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.



Thanks
why is cipherText being initialized and declared to an empty string in the first place? what's the logic behind it?
I thought that was a for loop? that's a do-loop?
What exactly does appending on that string mean?
 
Saloon Keeper
Posts: 11031
88
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Justin Robbins wrote:why is cipherText being initialized and declared to an empty string in the first place? what's the logic behind it?


If you don't initialize local variables they have random crap in them. And, because cipherText is a reference to a String, if it hasn't been initialized, the likely hood that it's pointing to some random place in memory that just happens to hold a String is nil.
 
Ranch Hand
Posts: 310
18
MS IE Linux
  • Likes 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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!
 
Sheriff
Posts: 9008
652
Mac OS X Spring VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Great explanation and putted effort in it, have a cow.

Only 1 side comment. Those 2 are equivalent in OP's particular case. In other cases where operands types are different on both sides, the difference may appear.

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.


Compound assignment operator "+=" does the hidden cast, and the difference could be seen in next case for instance:
There are other scenarios with slightly different behaviour when String and Object types are involved, but I can't remember them now

Once I've been instructed by Campbell Ritchie to read Java Puzzlers by Joshua Bloch, so found them there. Some of the cases you could find there are beyond comprehension, but it reveals where the programs in rare cases can flaw and could be very difficult to debug.
 
Andrew Polansky
Ranch Hand
Posts: 310
18
MS IE Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Liutauras and anonymous cowgiver for the cows!

I was unaware of this hidden cast behind "+=" operator. I even compiled it to see with my own eyes It looks like all shorthand assignment operators are doing such cast. I am a little shocked of that fact. Thanks for referring the book, I just checked it out on Amazon, it looks very interesting. I have added it to my to-read list.
 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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!



Fantastic answer! Thank you so very much for taking the time to write this. There were some parts I understood good and other parts I'd love to understand better and clarify my understanding or lack thereof with:

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.

Please help me understand. I think I am getting it, but there are holes in my understandings.

Thank you deeply,
My best
 
Sheriff
Posts: 7126
185
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Knute Snortum
Sheriff
Posts: 7126
185
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


This whole line here truly confuses me:



We are trying to get the new position (key value) of the decrypted letter. Since encrypting subtracted the shiftKey, we now add it to the character position in the alphabet. But what if the sum is greater than 25? (We have positions 0 - 25, that is, 26 positions.) We use a modulus operator (%). This operator says, Take the left hand value and divide it by the right hand value, then return the remainder. In this case, say the shift is 2 and the character position is 25 (Z). (2 + 25) % 26 = 27 % 26 = 1, which is the position for B.
 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.



Thanks a bunch!
Could you please explain the importance of knowing the remainder of the key and 26. I just don't understand what's happening there other than it gives us the remainder of those two values. Bu why that's useful here? why 26? If someone gives us 100 for the key why is it useful to take that 100 then MOD it by 26, that gives us R:22. Why is that important here? I wish I could understand the logic. So 26 goes into 100 3 times and leaves a remainder of 22, I sadly don't see how this helps. Why are we concerned with the remainder of the key and 26? If I understand that piece of the code I think it change the way I am thinking about this problem.

Thanks once more,
Kind regards


One last thing here with:


I think I understand what's happening. So we have the String var named plainText which then has a method attached to it charAt(i); this method which takes the letter at whichever 'i' it's increment at. So if the word is "HELLO" it will take i=0 to be the character 'H', BUT the part I need understanding on is once that happens and an 'H' is pulled out does it then right then and there convert to an ASCII value since its within a line that is declare to be of type int? so anytime we declare an int type line which is assigned to a char that char value is converted to an ASCII value?
Also, why is - 64 there?
 
Andrew Polansky
Ranch Hand
Posts: 310
18
MS IE Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Justin Robbins wrote:Fantastic answer! Thank you so very much for taking the time to write this.


I am glad I could help


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.


When we provide "C" for plainText and 2 for shiftKey it will return "e", not "A". Try to compile and run the code to see yourself. The original Caesar Cipher has shift to the left I believe, but In this code the shift has direction to the right.

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?


You could use code points of UTF-16 encoding instead of the string with alphabet, but that would require some additional corrections in the code to be sure that we do not go outside of the range where alphabet characters are stored. If you want I can rewrite that class to work that way, but I think it's better for now to understand how this class works in its current form.

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?


There is no such conversion between int and char in this code.

This is the code that initializes charPosition variable:


In the code above there are two method calls that return two different types. This code could be written in another way, keeping the same logic:


Methods do not must return their values to variables. They can return a value as an argument for other method.

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.


This is correct.

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?


ALPHABET.indexOf() doesn't use the i variable at all, it's only plainText.charAt(i) the only method that uses the i. Make sure you understand the explanation above of that line of code. If you understand it, you should get this part as well.

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'?


Let me break explanation into two parts.


What happens there, is adding shiftKey and charPosition together. Both of those variables are integers (int type). The role of the shiftKey you understand properly. The charPosition points to the position number of the letter in ALPHABET String. By adding shiftKey and charPosition together, you can get a new position in ALPHABET String that points to a shifted letter.

This illustration should make this process more clear:


The illustration shows shifting of letter 'c' by 2. The letter 'c' is stored under position 2 in the ALPHABET. When we add our shift number to that position, 2+2 would give us 4. And number 4, in the ALPHABET, points to letter 'e'. We can use this number to extract the character later in the code.


The % operator is used for modulo. You certainly know how modulo works. You see it in action every time you look at analog clock. Imagine that right now the clock shows hour 4 (no matter if am or pm). If you set the clock 6 hours forward, the clock will show hour 10. Now when you want to set the clock 6 hours forward again, it will show hour 4. Not hour 16, but hour 4, because passing hour 12 makes counting begin again from hour 1. Modulo works in very similar fashion, with this difference that it stars counting from zero.

Compile and run this example code. You will certainly get the point of modulo after that.


The point of modulo use in the CaesarCipher code is to make sure that position of the encrypted letter will be always within 0 and 25 numbers. Imagine that you want to shift letter "Z" by 2. Letter Z is the last one in ALPHABET, therefore it is on position 25. If you add 2 to it, you will get 27. There is no such position in the ALPHABET string, therefore modulo 26 is used. That way, (25+2)%26 will result in 1, which points to letter "b". Modulo simply makes the positions jumps to the beginning when they try to go out of ALPHABET positions range.


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.


charAt is a method that belongs to ALPHABET object that is an instance of String class. String is not a primitive type like int. It's a class that can be instantiated into objects. You can use charAt() from ALPHABET, because it's method of that object.


 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Adam Scheller
You're pro at this? Thanks so much for the picture it helped and all the details.
I began my own version of the cipher but I am having some problems with it, it's almost the way I want it but there is some buggy code. Ignoring the Scanner and prompts that I decided not to include here. I am able to get the right input for some things like "hello" 3 becomes "KHOOR" so it works there. But when I type something like t 24 or y 7 it ouputs nothing. Or when I type in zoro 3 I get }RUR. Why is it working perfectly for "hello" and "great" but all sorts of other things are outputting screwy things?

here is my code:



I keep thinking there is some sort of stipulation I have to add in there I can't figure out what though. Like that wrap around point of w?
 
Andrew Polansky
Ranch Hand
Posts: 310
18
MS IE Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.



Amazing advice!
for some reason I can't get it to output right. When I cast the letter + key and then input HELLO and 3 I get nothing back. Whereas before I would get KHOOR, but that was only for a limited range because if I typed in Y and 3 that would output \ symbol. So when it's not casted it pushes outside the bounds of the UTF alphabet but when it is casted nothing is returned back? It's perplexing me.


THANK YOU!
 
Andrew Polansky
Ranch Hand
Posts: 310
18
MS IE Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The parenthesis aren't doing a cast here, it just shows the compiler that addition should be done first before modulo. Just like in mathematics.

Here is why "HELLO" and shift 3 was giving you "KHOOR" earlier but not now. Let's say that the current iteration handles the first character 'H'.

Original code:

First operation that is made in this code is key % 26, because modulo operator is more important than addition operator. As your key is 3, the result of 3 % 26 is 3.

Second operation is addition of letter and result of key % 26. Letter is set to int 72, which is code point for character 'H'.

The result of this entire mathematical operation is then 72 + 3 which is 75. This number, 75, is code point of character 'K'. If you run this code for every character of "HELLO" String, you will get "KHOOR" as the result.


Updated code:

As we use parenthesis here, the order of operations is changed. First the sum of letter and key is calculated, then the result is applied to the modulo operation. Letter + key, which is 72+3, equals to 75. Now when 75 % 3 is calculated, we get 0, which is a non-printable NUL character. This is why nothing gets printed. All other character will be always within 0-25 range due to this modulo operation, which is why nothing gets ever printed.


If you want to deal with character code points instead of a String with alphabet, you can rewrite your code like this:


Analyze this code and try to figure out yourself why it prints KHOOR instead of nothing for input HELLO and key 3. Use pen and paper to do the calculations, it will make the task easier.

I will be leaving the city for a few days, probably I will be not able to check the forum in that time. I can give you a few exercises if you want to play with this code for a little more:

Exercise One: The code above will work properly only when user enters uppercase latin letters. Rewrite the code in a way where both input "hello" (lowercase latin characters) and "HELLO" (uppercase latin characters) will output "KHOOR".

Exercise Two: You wrote code that encrypts a String. Now write code that decrypts earlier encrypted String.

Exercise Three: You will notice that the code will generate improper results when user enters non-letter characters. Try to rewrite the code where user can additionally enter numbers. For input "hello3" user should get "KHOOR6" result (given that the shift key is 3). Input "hello9" should output "KHOOR2".

Exercise Four: Rewrite the code to make the result preserve the letters case. For input "HeLLo" the program should output "KhOOr".

Have fun
reply
    Bookmark Topic Watch Topic
  • New Topic