Reputation: 57
I am trying to do a project for my computer science class called "Encryption/Decryption"
The code goes as follows
import java.io.*;
import java.util.*;
import java.io.*;
import java.util.*;
public class Tester {
public static void main(String args[]) {
Scanner kbReader = new Scanner(System.in);
System.out.print("Enter a sentence that is to be encrypted: ");
String sntnc = kbReader.nextLine();
System.out.println("Original Sentence = " + sntnc);
Crypto myCryptObj = new Crypto();
String encryptdSntnc = myCryptObj.encrypt(sntnc);
System.out.println("Encrypted sentence = " + encryptdSntnc);
String decryptdSntnc = myCryptObj.decrypt(encryptdSntnc);
System.out.println("Decrypted sentence = " + decryptdSntnc);
}
}
class Crypto {
public String encrypt(String sntnc) {
sntnc = sntnc.replace("m", "ssad");
sntnc = sntnc.replace("b", "dug>?/");
sntnc = sntnc.replace("g", "jeb..w");
sntnc = sntnc.replace("v", "ag',r");
return sntnc;
}
public String decrypt(String sntnc) {
sntnc = sntnc.replace("ag',r", "v");
sntnc = sntnc.replace("ssad", "m");
sntnc = sntnc.replace("jeb..w", "g");
sntnc = sntnc.replace("dug>?/", "b");
return sntnc;
}
}
The problem isn't in the Tester
class, it's in the Crypto
class.
The input is: This is a very big morning.
And the code should output:
Enter a sentence that is to be encrypted: This is a very big morning.
Original Sentence: This is a very big morning.
Encrypted sentence: This is a ag',rery dug>?/ijeb..w ssadorninjeb..w.
Decrypted sentence: This is a very big morning.
But instead the Encrypted sentence
line is printing:
This is a ag',rery dujeb..w>?/ijeb..w ssadorninjeb..w.
The sntnc.replace
method is replacing the already replaced letters.
How do I fix it to where it won't replace things twice?
Upvotes: 2
Views: 475
Reputation: 1968
Your problem is that one replace intersect with other:
sntnc = sntnc.replace("g", "jeb..w");
sntnc = sntnc.replace("b", "dug>?/");
The first include a b
and the second include a g
even reorder the replaces will don't work.
You have to do all your replaces at once, try:
class Crypto {
public String encrypt(String sntnc) {
Pattern p = Pattern.compile("(m|g|b|v)");
Matcher m = p.matcher(sntnc);
StringBuffer sb = new StringBuffer();
while (m.find()) {
if(m.group(1).equals("m"))
m.appendReplacement(sb, "ssad");
if(m.group(1).equals("g"))
m.appendReplacement(sb, "jeb..w");
if(m.group(1).equals("b"))
m.appendReplacement(sb, "dug>?/");
if(m.group(1).equals("v"))
m.appendReplacement(sb, "ag',r");
}
m.appendTail(sb);
return sb.toString();
}
Upvotes: 0
Reputation: 106
Instead of using sntnc = sntnc.replaceAll("m", "ssad");
Try replacing each character with the appropriate encryption code and then save it in another string and return it.
`String s = "xyz";
for(int i = 0; i < sntnc.length(); i++)
{
char c = sntnc.charAt(i);
// Do your code here saving it in a new string say sntnc2
}`
return sntnc2;
May not be the most efficient method but using replaceAll("a","c")
as you've done replaces each character a
with c
from the start to the end of the string.
Upvotes: 0
Reputation: 137209
The problem comes from your logic of replacing the strings:
sntnc = sntnc.replaceAll("b", "dug>?/"); // <-- replaces with a "g" here
sntnc = sntnc.replaceAll("g", "jeb..w"); // <-- so that "g" is also getting replaced here
A simple solution is to drop using replaceAll
. Making your code works by re-ordering the replaceAll
calls is very fragile: you don't know that in the future someone will change what is getting replaced and break everything.
The solution is much simpler when building the String by iterating over the characters. Because we have an distinct temporary container when building the Strings, there are no conflicts when the replacements are happening.
public String encrypt(String sntnc) {
StringBuilder sb = new StringBuilder();
for (char ch : sntnc.toCharArray()) {
if (ch == 'm') sb.append("ssad");
else if (ch == 'b') sb.append("dug>?/");
else if (ch == 'g') sb.append("jeb..w");
else if (ch == 'v') sb.append("ag',r");
else sb.append(ch);
}
return sb.toString();
}
Upvotes: 6