Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 14 additions & 17 deletions src/main/java/com/thealgorithms/ciphers/Caesar.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
* @author khalil2535
*/
public class Caesar {
private static char normalizeShift(final int shift) {
return (char) (shift % 26);
private static int normalizeShift(final int shift) {
return ((shift % 26) + 26) % 26;
}

/**
Expand All @@ -22,21 +22,18 @@ private static char normalizeShift(final int shift) {
public String encode(String message, int shift) {
StringBuilder encoded = new StringBuilder();

final char shiftChar = normalizeShift(shift);
final int shiftChar = normalizeShift(shift);

final int length = message.length();
for (int i = 0; i < length; i++) {
// int current = message.charAt(i); //using char to shift characters because
// ascii
// is in-order latin alphabet
char current = message.charAt(i); // Java law : char + int = char
final char current = message.charAt(i);

if (isCapitalLatinLetter(current)) {
current += shiftChar;
encoded.append((char) (current > 'Z' ? current - 26 : current)); // 26 = number of latin letters
final int shifted = current + shiftChar;
encoded.append((char) (shifted > 'Z' ? shifted - 26 : shifted)); // 26 = number of latin letters
} else if (isSmallLatinLetter(current)) {
current += shiftChar;
encoded.append((char) (current > 'z' ? current - 26 : current)); // 26 = number of latin letters
final int shifted = current + shiftChar;
encoded.append((char) (shifted > 'z' ? shifted - 26 : shifted)); // 26 = number of latin letters
} else {
encoded.append(current);
}
Expand All @@ -53,17 +50,17 @@ public String encode(String message, int shift) {
public String decode(String encryptedMessage, int shift) {
StringBuilder decoded = new StringBuilder();

final char shiftChar = normalizeShift(shift);
final int shiftChar = normalizeShift(shift);

final int length = encryptedMessage.length();
for (int i = 0; i < length; i++) {
char current = encryptedMessage.charAt(i);
final char current = encryptedMessage.charAt(i);
if (isCapitalLatinLetter(current)) {
current -= shiftChar;
decoded.append((char) (current < 'A' ? current + 26 : current)); // 26 = number of latin letters
final int shifted = current - shiftChar;
decoded.append((char) (shifted < 'A' ? shifted + 26 : shifted)); // 26 = number of latin letters
} else if (isSmallLatinLetter(current)) {
current -= shiftChar;
decoded.append((char) (current < 'a' ? current + 26 : current)); // 26 = number of latin letters
final int shifted = current - shiftChar;
decoded.append((char) (shifted < 'a' ? shifted + 26 : shifted)); // 26 = number of latin letters
} else {
decoded.append(current);
}
Expand Down
23 changes: 23 additions & 0 deletions src/test/java/com/thealgorithms/ciphers/CaesarTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,29 @@ void caesarDecryptTest() {
assertEquals("Encrypt this text", cipherText);
}

@Test
void caesarEncryptWithNegativeShiftTest() {
// a shift of -1 must wrap 'A' backwards to 'Z', like a shift of +25 would
assertEquals("Z", caesar.encode("A", -1));
assertEquals("z", caesar.encode("a", -1));
assertEquals("EBIIL", caesar.encode("HELLO", -3));
}

@Test
void caesarDecryptWithNegativeShiftTest() {
assertEquals("A", caesar.decode("Z", -1));
assertEquals("HELLO", caesar.decode("EBIIL", -3));
}

@Test
void caesarNegativeShiftRoundTripTest() {
// encode followed by decode with the same shift must return the original text
for (int shift : new int[] {-1, -5, -25, -26, -27, -52}) {
String message = "The quick brown Fox";
assertEquals(message, caesar.decode(caesar.encode(message, shift), shift));
}
}

@Test
void caesarBruteForce() {
// given
Expand Down
Loading