I wanted to create a class that encrypts provided clear text using Caesar Cipher. Do you find my implementation clean? Any suggestions?
package biz.tugay.caesarcipher;
import java.util.Locale;
/*
Encyrpts a clear text using Caeser Cipher (https://en.wikipedia.org/wiki/Caesar_cipher)
with given shift amount.
Provided shift amount (i.e. key) must be a positive integer less than 26.
Only English alphabet is supported and encyrpted text will be in uppercase.
Shift amount 0 will return the same clear text.
*/
public final class CaesarCipher {
private final String clearText;
private final int key;
public CaesarCipher(final String clearText, final int key) {
if (clearText == null) {
throw new UnsupportedOperationException("Clear text to be encrypted can not be null!");
}
if (key < 0 || key > 26) {
throw new UnsupportedOperationException("Key must be between 0 and 26");
}
this.clearText = clearText;
this.key = key;
}
public String encryptText() {
final StringBuilder cipherTextBuilder = new StringBuilder();
final String clearTextUpperCase = clearText.toUpperCase(Locale.US);
final char[] clearTextUpperCaseCharArray = clearTextUpperCase.toCharArray();
for (final char c : clearTextUpperCaseCharArray) {
if (c < 65 || c > 90) { // If the character is not between A .. Z, append white space.
cipherTextBuilder.append(" ");
continue;
}
final Character encryptedCharacter = encryptCharacter(c);
cipherTextBuilder.append(encryptedCharacter);
}
return cipherTextBuilder.toString();
}
private Character encryptCharacter(final char c) {
final int initialShift = c + key;
final int finalShift;
if (initialShift > 90) {
// This is the case where we go beyond Z, we must cycle back to A.
finalShift = (initialShift % 90) + 64;
} else {
// We are in the boundries so no need to cycle..
finalShift = initialShift;
}
return (char) finalShift;
}
}
and I have 2 simple tests:
package biz.tugay.caesarcipher;
import org.junit.Assert;
import org.junit.Test;
public class CaesarCipherTest {
@Test
public void shouldReturnBCDForClearTextABCAndKey1() {
final String clearText = "abc";
final CaesarCipher caesarCipher = new CaesarCipher(clearText, 1);
final String encryptedText = caesarCipher.encryptText();
Assert.assertTrue(encryptedText.equals("BCD"));
}
@Test
public void shouldReturnAForZAndKey1() {
final String clearText = "Z";
final CaesarCipher caesarCipher = new CaesarCipher(clearText, 1);
final String encryptedText = caesarCipher.encryptText();
Assert.assertTrue(encryptedText.equals("A"));
}
}
UnsupportedOperationException
withIllegalArgumentException
at least for theclearText
validation. 2. Change the error message to "Key must be from 0 to 26". 3. To cycle the character, I find subtracting 90 from it to be intuitive than doing a remainder operation. \$\endgroup\$