• Post Reply Bookmark Topic Watch Topic
  • New Topic

Caesar Cipher  RSS feed

 
E. Chu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm trying to make a simple Caesar cipher that takes in a String as the first argument and a integer shift as the second argument. Can someone help me with what I have so far? Namely, there appears to be a problem with the loop and how I have declared the array - I want the converted characters to be put into a new array called newCharacterArray, converted back to a String and displayed in the command prompt window.



If anybody could give me any advice on how to proceed or where I've made my mistakes, I'd greatly appreciate it. After I get over this hump, my next assignment is making a Vigenere cipher.
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How are you starting that app? If that is intended to be the starting point, the parameter must be a String array (or a final String array), as described in the Java Language Specification.
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You need to do some arithmetic before you try that shifting. Write down some values for A (=1) B C X Y Z (=26), etc. before and after their shifting, and what formula you need to apply to get them always to turn into those letters.
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your newCharacterArray variable is declared as referencing a char array...but you never actually create the char array. So newCharacterArray is null. What you need is something like:
Note that I've put the [] before the variable, rather than after. Both are valid syntax, but this is more consistent with other usage: it reads as "newCharacterArray is a reference of type 'char array'". But it's the bit after the = that makes all the difference.

Quick tip - don't say "there appears to be a problem" - tell us what the problem is. E.g. what error message you're getting, if you're getting one. Or what behaviour you're getting that is different to what you expect. It makes it much easier for people to help you, which means you'll get an answer faster.
 
E. Chu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In regards to the Caesar cipher, it appears that I've accounted for everything expecting looping back to the beginning on the alphabet. For example, when I type <b>java Caesar "May the Force Be With You" 10</b>, into the command prompt I expect Wki dro Pybmo Lo Gsdr Iye. However, I've been getting Wk? ~ro Py|mo Lo as~r cy because the ASCII values corresponding to the character values are exceeding 65-90 (lowercase) and 97-122 (uppercase). I've spent a long time trying to work this; I'd really appreciate it if somebody gave me detailed instruction or commentary on my error(s). For more clarification on the error, please see the image that I've attached.



I've begun working on my Vigenere Cipher as well, and it's gotten to a state where it can take in input, but always gives the incorrect result. The program appears to loop each letter of the code word over every letter of the input string, resulting in a string much too long. The program does not appear to increment the array index of the codeCounter, resulting in a de facto "Caesar shift" of the first letter of the code word. I've reason to suspect that it's the for loop involving codeCounter that causes this abnormal behavior. Can somebody give me some helpful suggestions on fixing my code? I've also attached an image for clarification.

Caesar-Cipher.png
[Thumbnail for Caesar-Cipher.png]
Vigenere-Cipher.png
[Thumbnail for Vigenere-Cipher.png]
 
fred rosenberger
lowercase baba
Bartender
Posts: 12563
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
StopCoding (<--click that link and read the page).

What SHOULD happen with each letter?

I would also suggest you put your code into a method. Pass in one character and a shift amount, and have it return one character. That way, you can test it. You can debug it. you can see what exactly is happening letter by letter, rather than running an entire String through and hoping you get the right results.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
... and please don't post screenshots - post the actual error messages as text. It makes them searchable and quotable.
 
E. Chu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please note that I've revised my program since your post and have come somewhat closer to figuring out the eventual solution. I eliminated the problem with excess output. In regards to your first question, each letter should be shifted a number of spaces determined by the ASCII value of the corresponding code letter. For example, if 'a' was shifted by 'f' (6 spaces), the resulting value should be 'g'. Please note that this problem assumes as shift of 'a' to be 1, not 0.

We haven't learned about methods yet. Our professor - by his discretion - started introducing procedural programming these first three weeks of the semester. He reasoned that starting with object-oriented programming and use of methods was too harsh an introduction.
 
E. Chu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Ulf Dittmer

There are no error messages in the traditional sense. It's not that it doesn't compile, it's that wrong output is given. It's the logical component of the problem that I'm trying to solve. Please understand that it's hard to illustrate the situation sufficiently without illustration.
 
fred rosenberger
lowercase baba
Bartender
Posts: 12563
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
E. Chu wrote: In regards to your first question, each letter should be shifted a number of spaces determined by the ASCII value of the corresponding code letter. For example, if 'a' was shifted by 'f' (6 spaces), the resulting value should be 'g'. Please note that this problem assumes as shift of 'a' to be 1, not 0.

that is an example. That's fine for illustrative purposes, but it isn't what you need to do.

You need to write down in English (or other natural language of choice) the EXACT steps you should take if you were doing this with nothing but pencil and paper. You need to then revise those steps, breaking them down into simpler and simpler components. You need to get to the point where you could hand those instructions to a 10 year old child, walk away, and reasonably expect them to be able to give you the output you desire.

Only when the above is done should you consider writing a single line of code.

E. Chu wrote: We haven't learned about methods yet. Our professor - by his discretion - started introducing procedural programming these first three weeks of the semester. He reasoned that starting with object-oriented programming and use of methods was too harsh an introduction.

sigh...I hate professors who figure you should learn the wrong way to do it before introducing you the right way. By that point everyone will have developed all kinds of nasty habits to break.
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
E. Chu wrote: . . . I've begun working on my Vigenere Cipher as well, . . .
What a bad idea, starting something new before you finished the first thing.

What is the formula you are using to change y to i? As several people have already told you, you need to work out the formula first, before you try writing any code.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please understand that it's hard to illustrate the situation sufficiently without illustration.

I beg to differ. The images show only text of various kinds: textual input/output and program code. What I said applies as much to that as to error messages.
 
E. Chu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Ulf Dittmer

I want to avoid confusion as much as possible. In my opinion, there is no appreciable benefit to contextualizing the information presented in the image. At worst, it is ignored. At best, it compliments what I'm trying to present my problem to be.
 
E. Chu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In any case, I have updated my source code. I run into the same problem as my Caesar cipher, I am off by an ASCII value of 26 on values exceeding 122 (uppercase) and 90 (lowercase).



I have followed Fred's helpful suggestion on writing everything else. Should you desire proof of this, I can provide it.


java vigenere 'May the Force Be With You' obiwan should give Bch uvt Olsqt Kb Kxvq Zcj. However, it gives \c? uvt O?sqt K| exvq Z}?. Again, all differing ASCII values appear to be off by 26. For example the '?' in '\c?' returns a ASCII value of 130 while it should return 104 ('h').
 
fred rosenberger
lowercase baba
Bartender
Posts: 12563
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
did you work out the math on this line:


when your currentCharacter is 'M' and your codeArray[currentCodeInteger] is 'o'?

'o' is equal to 111.

111 - 96 is 15.

15 mod 26 is 15.

'M' is equal to 77.

77 + 15 is 92.

and 92 is the ascii value for a '\'.


Your code is doing exactly what you told it to do.
 
fred rosenberger
lowercase baba
Bartender
Posts: 12563
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
E. Chu wrote:I want to avoid confusion as much as possible. In my opinion, there is no appreciable benefit to contextualizing the information presented in the image. At worst, it is ignored. At best, it compliments what I'm trying to present my problem to be.

For what it's worth, you have come to this site and asked for help. You were told "we find it works best when you present your information THIS way". Replying with "Nope, I think you're wrong and I'm gonna do it how I want" is very likely to turn off a lot of folk, and they'll not bother helping you any more.

just something to consider.
 
Junilu Lacar
Sheriff
Posts: 11476
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You might find clues as to why your formula is not working if you search for wrapping values with modulo in java. Also consider that 'Z' - 'A' == 'z' - 'a' and that the expression (char) ('A' + ('B' - 'A')) == 'B' is true and will be true for all consecutive letters with the same case.
 
E. Chu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm getting a lot warmer. Now, all the lowercase letters transform properly. Unfortunately, not the same can be said of the uppercase ones.



I figured that using multiple if loops to account for looping back to the beginning of the alphabet would work. However, I have no clue why the uppercase loop is suspect. I've computed the ASCII values and am utterly confused on the behavior of the uppercase if loops. For example, java "May the Force Be With You" obiwan should give Bch uvt Olsqt Kb Kxvq Zcj. It gives cch uvt Vlsqt Rb lxvq acj.

UPDATE: I got my Caesar cipher to work! Below is the source for those interested.


 
fred rosenberger
lowercase baba
Bartender
Posts: 12563
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would suggest you work through the the example as I did above, to see why it is returning the value you don't want.
 
Junilu Lacar
Sheriff
Posts: 11476
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're making it way too complicated. If you use the % operator as a number of people have hinted at, encoding can be done with one (1) line of code. For the Caesar cipher, you only need a single for-loop that iterates over the characters in the plaintext string and encodes each one in turn. For the Vignere cipher, I'd use a Map<Character, Cipher> and a formula that again uses % to figure out the proper cipher to use to encode the current plaintext character. The core solution should really only consist of two methods and neither one would be more than 5 lines of code long.
 
E. Chu
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Fred Rosenberger

Thank you for your suggestion. I've already worked through many similar cases in the context of my program. In regards to Ulf Dittmer's preferences, please realize that he is a single person. I would not take him to represent "we". As I implied, different people can choose to or choose not to look at the images I've posted. It's as simple as that.

@Junilu Lacar

I am in a first-semester CS course with a professor that hasn't begun teaching methods, objects or object-oriented programming. I honestly have no idea what Map<Character or Cipher> mean. There was little chance I could have done the things that experienced programmers have been doing for months or years given my exposure.

In any case, my awesome TA helped me eliminate a pesky off-by-one error. It appeared that factor was the final issue preventing my program from executing correctly. My final code is presented below.

Caesar Cipher


Vigenere Cipher
 
Junilu Lacar
Sheriff
Posts: 11476
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
E. Chu wrote:I am in a first-semester CS course with a professor that hasn't begun teaching methods, objects or object-oriented programming. I honestly have no idea what Map<Character or Cipher> mean. There was little chance I could have done the things that experienced programmers have been doing for months or years given my exposure.


No worries. Keep this version of your code socked away somewhere and when you learn about methods and other ways of organizing your code, go back and try to clean it up. It's a great way to exercise and develop your programming skills. As an example how a method can help compartmentalize and focus your code, consider this implementation:


This may seem a bit cryptic at first glance, especially lines 9 and 10 but with a little bit of char/int math knowledge, it's not that hard to figure out what's going on. A call to this method would replace most of your if-statements.
 
fred rosenberger
lowercase baba
Bartender
Posts: 12563
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
E. Chu wrote:@Fred Rosenberger

Thank you for your suggestion. I've already worked through many similar cases in the context of my program.

But if one is giving you the wrong answer, work through it. step by step. I often will put System.out.println() statements in my code - only to remove them later - to validate my assumptions on how the math is working out. Clearly the code was doing something different than what you thought. The trick is to figure out where exactly your assumptions are wrong (and even what your assumptions are).
E. Chu wrote: In regards to Ulf Dittmer's preferences, please realize that he is a single person. I would not take him to represent "we". As I implied, different people can choose to or choose not to look at the images I've posted. It's as simple as that.

It's not just Ulf's opinion. It is a posted in one of our FAQ's: PostTextNotScreenshots

You can find other suggestions here: HowToAskQuestionsOnJavaRanch

Nobody will force you to do it. I was merely suggesting that when you go into someone else's house, you follow their suggestions on how to behave. Ulf has been around here for nine years and has over 38,000 posts. He has the title of "Marshall", which pretty much means he runs the forums (you can see what the titles mean here). He probably has a pretty good idea how things work best.
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All those numbers like 122 and 26 look bad. You can use all sorts of things instead which make their meanings obvious.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!