Reputation: 39
So I've been trying to make this simple encryption program but I can't seem to figure out some things. The phrase I need to enter is
This is a very big morning.
When I enter it though it returns the string
This is a ag',rery dug>?/ijeb..w ssadorninjeb..w
Instead I return
This is a ajedg>P/..w',rery dg>P/ijedg>P/..w ssadorninjedg>P/..w
I don't understand why and how to fix it? I've been learning java for around a month now so I'm still fresh and if there's a similar question that's already been answered please link me there and I'll delete this post.
Here's the code:
import static java.lang.System.out;
import java.util.Scanner;
class Encryption {
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
Crypto user1 = new Crypto();
out.print("Please enter in a sentence: ");
String user = userInput.nextLine();
user1.encrypt(user);
out.print(user1.getEncrypt());
}
}
public Crypto() { }
public String myEn;
public void encrypt(String Sentence) {
myEn = Sentence.replaceAll("v","ag',r")
.replaceAll("m" , "ssad")
.replaceAll("g" , "jeb..w")
.replaceAll("b" , "dg>P/");
}
public String getEncrypt() {
return myEn;
}
}
Upvotes: 0
Views: 169
Reputation: 124215
As others already told you problem is that you are replacing characters in few iterations (replaceAll calls) instead of one. If you want to prevent replacing characters that ware used to replace other characters you can use appendReplacement
and appendTail
from Matcher
class.
Here is how you can do it like
// We need to store somewhere info about original and its replacement
// so we will use Map
Map<String, String> replacements = new HashMap<>();
replacements.put("v", "ag',r");
replacements.put("m", "ssad");
replacements.put("g", "jeb..w");
replacements.put("b", "dg>P/");
// we need to create pattern which will find characters we want to replace
Pattern pattern = Pattern.compile("[vmgb]");//this will do
Matcher matcher = pattern.matcher("This is a very big morning.");
StringBuffer sb = new StringBuffer();// this will be used to create
// string with replaced characters
// lets start replacing process
while (matcher.find()) {//first we need to find our characters
// then pick from map its replacement
String replacement = replacements.get(matcher.group());
// and pass it to appendReplacement method
matcher.appendReplacement(sb, replacement);
// we repeat this process until original string has no more
// characters to replace
}
//after all we need to append to StringBuffer part after last replacement
matcher.appendTail(sb);
System.out.println(sb);
Output:
This is a ag',rery dg>P/ijeb..w ssadorninjeb..w.
Voilà.
Upvotes: 0
Reputation: 424993
Firstly, you should use replace()
, not replaceAll()
. Both replace all matches found, but replaceAll() uses regex to match and replace() uses plain text.
Next, your replacements are getting in the way of each other, so use a StringBuffer and work from the eighth and end backwards replacing one character at a time.
Decryption should likewise work one character at a time starting from the left.
Upvotes: 0
Reputation: 10959
When you replace the g
its replacement contains a b
so then when you replace the b
's you get all the b
's from the g
replacement also replaced. and also for the v
's
What you could do is
Sentence.replaceAll("g" , "jeb..w")
.replaceFirst("b" , "dg>P/") // as no g's before b's and only want to replace the first
.replaceFirst("v","ag',r")
.replaceFirst("m" , "ssad");
But this only works for this one sentence.
What you could do:
Upvotes: 0
Reputation: 91619
The reason you're getting the different output is because the chained replaces take the return value of the previous replaces. So in your case, if there was a v
, it would be changed with ag',r
which has a g
in it. That g
would then trigger replaceAll("g" , "jeb..w")
.
To avoid this from happening, you should change the order of the replaces:
Sentence.replaceAll("g" , "jeb..w")
.replaceAll("b" , "dg>P/")
.replaceAll("v","ag',r")
.replaceAll("m" , "ssad");
However, the first two replace statements can't be fixed because one replaces b
with a string that has a g
in it, and vice-versa, so you might want to change the characters you're replacing.
Upvotes: 2