I wrote this Caesar cipher and decipher just for the sake of practising OOP (previous answers to my java questions all seem to point to OOPness).
What it is:
The Caesar cipher is one of the earliest known and simplest ciphers. It is a type of substitution cipher in which each letter in the plaintext is 'shifted' a certain number of places down the alphabet.
Currently I have a Cipher
interface and a CaesarCipher
class: I am planning to add a Vigenère Cipher soon.
Code:
Cipher.java
public interface Cipher {
public String cipher(String text);
public String decipher(String cipherText);
public char getCipheredChar(char textChar);
public char getDecipheredChar(char cipherChar);
}
CaesarCipher.java
public class CaesarCipher implements Cipher {
private static final int LETTERS = 'Z' - 'A' + 1;
private int shift;
public CaesarCipher(int shift) {
if (shift < -LETTERS || shift > LETTERS) {
throw new IllegalArgumentException("The value of shift: " + shift
+ " is invalid.");
}
this.shift = shift;
}
public int getShift() {
return shift;
}
@Override
public String cipher(String text) {
char[] result = text.toCharArray();
for (int i = 0; i < result.length; i++) {
result[i] = getCipheredChar(result[i]);
}
return new String(result);
}
@Override
public String decipher(String cipherText) {
this.shift = -shift;
String result = cipher(cipherText);
this.shift = -shift;
return result;
}
@Override
public char getCipheredChar(char textChar) {
if (textChar > 'A' && textChar < 'z') {
char result = (char) (textChar + shift);
char compare = Character.isUpperCase(textChar) ? 'Z' : 'z';
char lowCompare = Character.isUpperCase(textChar) ? 'A' : 'a';
return (char) (result > compare ? result - 26
: (result < lowCompare ? result + 26 : result));
}
return textChar;
}
@Override
public char getDecipheredChar(char cipherChar) {
this.shift = -shift;
char result = getCipheredChar(cipherChar);
this.shift = -shift;
return result;
}
}
And tests!
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class TestCipher {
@Test
public void testShift1() {
CaesarCipher cipher = new CaesarCipher(1);
assertEquals("AaBbCc", cipher.decipher("BbCcDd"));
assertEquals("Bzdrzq", cipher.decipher("Caesar"));
assertEquals("Bzdrzq Bhogdq...", cipher.decipher("Caesar Cipher..."));
}
@Test
public void testShift5() {
CaesarCipher cipher = new CaesarCipher(5);
assertEquals("AaBbCc", cipher.decipher("FfGgHh"));
assertEquals("Xvznvm", cipher.decipher("Caesar"));
assertEquals("Xvznvm Xdkczm...", cipher.decipher("Caesar Cipher..."));
}
}
Concerns:
- Are my tests fine?
- Is my OOP structure good?
- And as usual, anything else?