From d8fff407fbaa79a50668573cb27114db6d33f7e4 Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Thu, 10 Oct 2024 08:04:50 +0530 Subject: [PATCH 01/10] Add AtbashCipher.java --- .../thealgorithms/ciphers/AtbashCipher.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/main/java/com/thealgorithms/ciphers/AtbashCipher.java diff --git a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java new file mode 100644 index 000000000000..462029d38f2d --- /dev/null +++ b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java @@ -0,0 +1,69 @@ +/* +* The Atbash cipher is a simple substitution cipher that replaces each letter +* in the alphabet with its reverse. +* For example, 'A' becomes 'Z', 'B' becomes 'Y', and so on. It works +* identically for both uppercase and lowercase letters. +* It's a symmetric cipher, meaning applying it twice returns the original text. +* Hence, the encrypting and the decrypting functions are identical +* +* @author https://github.com/Krounosity +* Learn more: https://en.wikipedia.org/wiki/Atbash +*/ + +package com.thealgorithms.ciphers; + +public class AtbashCipher { + + private String toConvert; + + // Default constructor. + AtbashCipher() { + } + + // String setting constructor. + AtbashCipher(String str) { + toConvert = str; + } + + // String getter method. + public String getString() { + return toConvert; + } + + // String setter method. + public void setString(String str) { + toConvert = str; + } + + // Checking whether the current character is capital. + private boolean isCapital(char ch) { + return ch >= 'A' && ch <= 'Z'; + } + + // Checking whether the current character is smallcased. + private boolean isSmall(char ch) { + return ch >= 'a' && ch <= 'z'; + } + + // Converting text to atbash cipher code or vice versa. + public String convert() { + + // Using StringBuilder to store new string. + StringBuilder convertedString = new StringBuilder(); + + // Iterating for each character. + for (char ch : toConvert.toCharArray()) { + + // If the character is smallcased. + if (isSmall(ch)) + convertedString.append((char) ('z' - (ch - 'a'))); + // If the character is capital cased. + else if (isCapital(ch)) + convertedString.append((char) ('Z' - (ch - 'A'))); + // Non-alphabetical character. + else + convertedString.append(ch); + } + return convertedString.toString(); + } +} \ No newline at end of file From ef9442e2d72b3840b1c1f9f1cfd81d75974fbc7f Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Thu, 10 Oct 2024 08:04:57 +0530 Subject: [PATCH 02/10] Add AtbashTest.java --- .../com/thealgorithms/ciphers/AtbashTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/test/java/com/thealgorithms/ciphers/AtbashTest.java diff --git a/src/test/java/com/thealgorithms/ciphers/AtbashTest.java b/src/test/java/com/thealgorithms/ciphers/AtbashTest.java new file mode 100644 index 000000000000..57bece8b3a98 --- /dev/null +++ b/src/test/java/com/thealgorithms/ciphers/AtbashTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class AtbashTest { + + @Test + public void atbashEncrypt() { + AtbashCipher normalToEncrypt = new AtbashCipher( + "Hello World! 123, @cipher abcDEF ZYX 987 madam zzZ Palindrome!"); + String expectedText = "Svool Dliow! 123, @xrksvi zyxWVU ABC 987 nzwzn aaA Kzormwilnv!"; + + normalToEncrypt.setString(normalToEncrypt.convert()); + + assertEquals(expectedText, normalToEncrypt.getString()); + } + + @Test + public void atbashDecrypt() { + AtbashCipher encryptToNormal = new AtbashCipher( + "Svool Dliow! 123, @xrksvi zyxWVU ABC 987 nzwzn aaA Kzormwilnv!"); + String expectedText = "Hello World! 123, @cipher abcDEF ZYX 987 madam zzZ Palindrome!"; + + encryptToNormal.setString(encryptToNormal.convert()); + + assertEquals(expectedText, encryptToNormal.getString()); + } +} \ No newline at end of file From 8d62a3f5e900a528309a1980e85a1f182eb1b3ef Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Thu, 10 Oct 2024 08:10:27 +0530 Subject: [PATCH 03/10] Update DIRECTORY.md --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index a1a53cb2926c..912b7646a0cd 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -48,6 +48,7 @@ * [AES](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AES.java) * [AESEncryption](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AESEncryption.java) * [AffineCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AffineCipher.java) + * [AtbashCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java) * [Autokey](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Autokey.java) * [Blowfish](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Blowfish.java) * [Caesar](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Caesar.java) @@ -657,6 +658,7 @@ * [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java) * [AESEncryptionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AESEncryptionTest.java) * [AffineCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AffineCipherTest.java) + * [AtbashTest](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AtbashTest.java) * [AutokeyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AutokeyTest.java) * [BlowfishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java) * [CaesarTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/CaesarTest.java) From 26a9dd20fc5356ac4425d700ffb2509ba74b4b71 Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Thu, 10 Oct 2024 08:25:08 +0530 Subject: [PATCH 04/10] Fix --- .../java/com/thealgorithms/ciphers/AtbashCipher.java | 12 +++++++----- .../java/com/thealgorithms/ciphers/AtbashTest.java | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java index 462029d38f2d..158350199f23 100644 --- a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java @@ -5,7 +5,6 @@ * identically for both uppercase and lowercase letters. * It's a symmetric cipher, meaning applying it twice returns the original text. * Hence, the encrypting and the decrypting functions are identical -* * @author https://github.com/Krounosity * Learn more: https://en.wikipedia.org/wiki/Atbash */ @@ -55,15 +54,18 @@ public String convert() { for (char ch : toConvert.toCharArray()) { // If the character is smallcased. - if (isSmall(ch)) + if (isSmall(ch)) { convertedString.append((char) ('z' - (ch - 'a'))); + } // If the character is capital cased. - else if (isCapital(ch)) + else if (isCapital(ch)) { convertedString.append((char) ('Z' - (ch - 'A'))); + } // Non-alphabetical character. - else + else { convertedString.append(ch); + } } return convertedString.toString(); } -} \ No newline at end of file +} diff --git a/src/test/java/com/thealgorithms/ciphers/AtbashTest.java b/src/test/java/com/thealgorithms/ciphers/AtbashTest.java index 57bece8b3a98..76e1df0139b4 100644 --- a/src/test/java/com/thealgorithms/ciphers/AtbashTest.java +++ b/src/test/java/com/thealgorithms/ciphers/AtbashTest.java @@ -27,4 +27,4 @@ public void atbashDecrypt() { assertEquals(expectedText, encryptToNormal.getString()); } -} \ No newline at end of file +} From 3fe4ca50e702bc53e95e53db7d543aafd64dec4f Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Thu, 10 Oct 2024 08:28:28 +0530 Subject: [PATCH 05/10] Clang fix --- src/main/java/com/thealgorithms/ciphers/AtbashCipher.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java index 158350199f23..e372df5d53bc 100644 --- a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java @@ -1,5 +1,4 @@ -/* -* The Atbash cipher is a simple substitution cipher that replaces each letter +/* The Atbash cipher is a simple substitution cipher that replaces each letter * in the alphabet with its reverse. * For example, 'A' becomes 'Z', 'B' becomes 'Y', and so on. It works * identically for both uppercase and lowercase letters. From e38d50823aed7d3fba4972e240b98ca485b517cf Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Thu, 10 Oct 2024 08:39:34 +0530 Subject: [PATCH 06/10] Fix --- src/main/java/com/thealgorithms/ciphers/AtbashCipher.java | 3 ++- src/test/java/com/thealgorithms/ciphers/AtbashTest.java | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java index e372df5d53bc..d33178916b2d 100644 --- a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java @@ -1,4 +1,5 @@ -/* The Atbash cipher is a simple substitution cipher that replaces each letter +/** +* The Atbash cipher is a simple substitution cipher that replaces each letter * in the alphabet with its reverse. * For example, 'A' becomes 'Z', 'B' becomes 'Y', and so on. It works * identically for both uppercase and lowercase letters. diff --git a/src/test/java/com/thealgorithms/ciphers/AtbashTest.java b/src/test/java/com/thealgorithms/ciphers/AtbashTest.java index 76e1df0139b4..26812cf2b0d4 100644 --- a/src/test/java/com/thealgorithms/ciphers/AtbashTest.java +++ b/src/test/java/com/thealgorithms/ciphers/AtbashTest.java @@ -8,8 +8,7 @@ public class AtbashTest { @Test public void atbashEncrypt() { - AtbashCipher normalToEncrypt = new AtbashCipher( - "Hello World! 123, @cipher abcDEF ZYX 987 madam zzZ Palindrome!"); + AtbashCipher normalToEncrypt = new AtbashCipher("Hello World! 123, @cipher abcDEF ZYX 987 madam zzZ Palindrome!"); String expectedText = "Svool Dliow! 123, @xrksvi zyxWVU ABC 987 nzwzn aaA Kzormwilnv!"; normalToEncrypt.setString(normalToEncrypt.convert()); @@ -19,8 +18,7 @@ public void atbashEncrypt() { @Test public void atbashDecrypt() { - AtbashCipher encryptToNormal = new AtbashCipher( - "Svool Dliow! 123, @xrksvi zyxWVU ABC 987 nzwzn aaA Kzormwilnv!"); + AtbashCipher encryptToNormal = new AtbashCipher("Svool Dliow! 123, @xrksvi zyxWVU ABC 987 nzwzn aaA Kzormwilnv!"); String expectedText = "Hello World! 123, @cipher abcDEF ZYX 987 madam zzZ Palindrome!"; encryptToNormal.setString(encryptToNormal.convert()); From 5a67d8e6c18e06862337049ea085ba37cac89d06 Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Thu, 10 Oct 2024 08:40:52 +0530 Subject: [PATCH 07/10] Commenting fix --- src/main/java/com/thealgorithms/ciphers/AtbashCipher.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java index d33178916b2d..9a845dfe4ccd 100644 --- a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java @@ -1,3 +1,5 @@ +package com.thealgorithms.ciphers; + /** * The Atbash cipher is a simple substitution cipher that replaces each letter * in the alphabet with its reverse. @@ -9,8 +11,6 @@ * Learn more: https://en.wikipedia.org/wiki/Atbash */ -package com.thealgorithms.ciphers; - public class AtbashCipher { private String toConvert; From 3879720906d77d4d0ddaeed3e718b65f2e759299 Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Thu, 10 Oct 2024 08:42:24 +0530 Subject: [PATCH 08/10] Fix commenting --- .../thealgorithms/ciphers/AtbashCipher.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java index 9a845dfe4ccd..8ce4688f5186 100644 --- a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java @@ -1,15 +1,17 @@ package com.thealgorithms.ciphers; /** -* The Atbash cipher is a simple substitution cipher that replaces each letter -* in the alphabet with its reverse. -* For example, 'A' becomes 'Z', 'B' becomes 'Y', and so on. It works -* identically for both uppercase and lowercase letters. -* It's a symmetric cipher, meaning applying it twice returns the original text. -* Hence, the encrypting and the decrypting functions are identical -* @author https://github.com/Krounosity -* Learn more: https://en.wikipedia.org/wiki/Atbash -*/ + * The Atbash cipher is a simple substitution cipher that replaces each letter + * in the alphabet with its reverse. + * For example, 'A' becomes 'Z', 'B' becomes 'Y', and so on. It works + * identically for both uppercase and lowercase letters. + * It's a symmetric cipher, meaning applying it twice returns the original text. + * Hence, the encrypting and the decrypting functions are identical + * + * @author https://github.com/Krounosity + * + * Learn more: https://en.wikipedia.org/wiki/Atbash + */ public class AtbashCipher { From ceee53a93eebcd817a2918a44a7df3bf3e2dceef Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Thu, 10 Oct 2024 08:45:14 +0530 Subject: [PATCH 09/10] Fix commenting --- src/main/java/com/thealgorithms/ciphers/AtbashCipher.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java index 8ce4688f5186..c3b673144c63 100644 --- a/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java @@ -7,9 +7,7 @@ * identically for both uppercase and lowercase letters. * It's a symmetric cipher, meaning applying it twice returns the original text. * Hence, the encrypting and the decrypting functions are identical - * * @author https://github.com/Krounosity - * * Learn more: https://en.wikipedia.org/wiki/Atbash */ From c50b777b8a64881eae86089bed144793910310ad Mon Sep 17 00:00:00 2001 From: Varnan Rathod Date: Sun, 13 Oct 2024 12:43:59 +0530 Subject: [PATCH 10/10] Add main, test for Rail Fence Cipher and update README.md --- DIRECTORY.md | 4 +- .../ciphers/RailFenceCipher.java | 129 ++++++++++++++++++ .../thealgorithms/ciphers/RailFenceTest.java | 62 +++++++++ 3 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java create mode 100644 src/test/java/com/thealgorithms/ciphers/RailFenceTest.java diff --git a/DIRECTORY.md b/DIRECTORY.md index e022ddc23e5a..bb32c051a333 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -60,6 +60,7 @@ * [PlayfairCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java) * [Polybius](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Polybius.java) * [ProductCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ProductCipher.java) + * [RailFenceCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java) * [RSA](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RSA.java) * [SimpleSubCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java) * [Vigenere](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Vigenere.java) @@ -664,7 +665,7 @@ * [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java) * [AESEncryptionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AESEncryptionTest.java) * [AffineCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AffineCipherTest.java) - * [AtbashTest](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AtbashTest.java) + * [AtbashTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AtbashTest.java) * [AutokeyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AutokeyTest.java) * [BlowfishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java) * [CaesarTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/CaesarTest.java) @@ -673,6 +674,7 @@ * [HillCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/HillCipherTest.java) * [PlayfairTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java) * [PolybiusTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java) + * [RailFenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RailFenceTest.java) * [RSATest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RSATest.java) * [SimpleSubCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java) * [VigenereTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/VigenereTest.java) diff --git a/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java b/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java new file mode 100644 index 000000000000..5e53bdc7c4c8 --- /dev/null +++ b/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java @@ -0,0 +1,129 @@ +package com.thealgorithms.ciphers; + +import java.util.Arrays; + +/** + * The rail fence cipher (also called a zigzag cipher) is a classical type of transposition cipher. + * It derives its name from the manner in which encryption is performed, in analogy to a fence built with horizontal rails. + * https://en.wikipedia.org/wiki/Rail_fence_cipher + * @author https://github.com/Krounosity + */ + + + public class RailFenceCipher { + + // Encrypts the input string using the rail fence cipher method with the given number of rails. + public String encrypt(String str, int rails) { + + // Base case of single rail or rails are more than the number of characters in the string + if(rails == 1 || rails>=str.length()) return str; + + // Boolean flag to determine if the movement is downward or upward in the rail matrix. + boolean down = true; + // Create a 2D array to represent the rails (rows) and the length of the string (columns). + char[][] strRail = new char[rails][str.length()]; + + // Initialize all positions in the rail matrix with a placeholder character ('\n'). + for (int i = 0; i < rails; i++) + Arrays.fill(strRail[i], '\n'); + + int row = 0; // Start at the first row + int col = 0; // Start at the first column + + int i = 0; + + // Fill the rail matrix with characters from the string based on the rail pattern. + while (col < str.length()) { + // Change direction to down when at the first row. + if (row == 0) down = true; + // Change direction to up when at the last row. + else if (row == rails - 1) down = false; + + // Place the character in the current position of the rail matrix. + strRail[row][col] = str.charAt(i); + col++; // Move to the next column. + + // Move to the next row based on the direction. + if (down) row++; + else row--; + + i++; + } + + // Construct the encrypted string by reading characters row by row. + StringBuilder encryptedString = new StringBuilder(); + for (char[] chRow : strRail) { + for (char ch : chRow) { + if (ch != '\n') encryptedString.append(ch); + } + } + + return encryptedString.toString(); + } + + // Decrypts the input string using the rail fence cipher method with the given number of rails. + public String decrypt(String str, int rails) { + + // Base case of single rail or rails are more than the number of characters in the string + if(rails == 1 || rails>=str.length()) return str; + + // Boolean flag to determine if the movement is downward or upward in the rail matrix. + boolean down = true; + + // Create a 2D array to represent the rails (rows) and the length of the string (columns). + char[][] strRail = new char[rails][str.length()]; + + int row = 0; // Start at the first row + int col = 0; // Start at the first column + + // Mark the pattern on the rail matrix using '*'. + while (col < str.length()) { + + // Change direction to down when at the first row. + if (row == 0) down = true; + + // Change direction to up when at the last row. + else if (row == rails - 1) down = false; + + // Mark the current position in the rail matrix. + strRail[row][col] = '*'; + col++; // Move to the next column. + + // Move to the next row based on the direction. + if (down) row++; + else row--; + } + + int index = 0; // Index to track characters from the input string. + // Fill the rail matrix with characters from the input string based on the marked pattern. + for (int i = 0; i < rails; i++) { + for (int j = 0; j < str.length(); j++) { + if (strRail[i][j] == '*') { + strRail[i][j] = str.charAt(index++); + } + } + } + + // Construct the decrypted string by following the zigzag pattern. + StringBuilder decryptedString = new StringBuilder(); + row = 0; // Reset to the first row + col = 0; // Reset to the first column + + while (col < str.length()) { + // Change direction to down when at the first row. + if (row == 0) down = true; + // Change direction to up when at the last row. + else if (row == rails - 1) down = false; + + // Append the character from the rail matrix to the decrypted string. + decryptedString.append(strRail[row][col]); + col++; // Move to the next column. + + // Move to the next row based on the direction. + if (down) row++; + else row--; + } + + return decryptedString.toString(); + } +} diff --git a/src/test/java/com/thealgorithms/ciphers/RailFenceTest.java b/src/test/java/com/thealgorithms/ciphers/RailFenceTest.java new file mode 100644 index 000000000000..2bfa704e3d0b --- /dev/null +++ b/src/test/java/com/thealgorithms/ciphers/RailFenceTest.java @@ -0,0 +1,62 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class RailFenceTest { + + @Test + void testEncryption() { + RailFenceCipher cipher = new RailFenceCipher(); + + String input = "We are discovered! Flee at once"; + int rails = 3; + String encrypted = cipher.encrypt(input, rails); + assertEquals("Wrivdlaneaedsoee!Fe toc cr e e", encrypted); + + String singleChar = "A"; + int singleRail = 2; + String encryptedSingleChar = cipher.encrypt(singleChar, singleRail); + assertEquals("A", encryptedSingleChar); + + String shortString = "Hello"; + int moreRails = 10; + String encryptedShortString = cipher.encrypt(shortString, moreRails); + assertEquals("Hello", encryptedShortString); + + String inputSingleRail = "Single line"; + int singleRailOnly = 1; + String encryptedSingleRail = cipher.encrypt(inputSingleRail, singleRailOnly); + assertEquals("Single line", encryptedSingleRail); + } + + @Test + void testDecryption() { + RailFenceCipher cipher = new RailFenceCipher(); + + // Scenario 1: Basic decryption with multiple rails + String encryptedInput = "Wrivdlaneaedsoee!Fe toc cr e e"; + int rails = 3; + String decrypted = cipher.decrypt(encryptedInput, rails); + assertEquals("We are discovered! Flee at once", decrypted); + + // Scenario 2: Single character string decryption + String encryptedSingleChar = "A"; + int singleRail = 2; // More than 1 rail + String decryptedSingleChar = cipher.decrypt(encryptedSingleChar, singleRail); + assertEquals("A", decryptedSingleChar); + + // Scenario 3: String length less than the number of rails + String encryptedShortString = "Hello"; + int moreRails = 10; // More rails than characters + String decryptedShortString = cipher.decrypt(encryptedShortString, moreRails); + assertEquals("Hello", decryptedShortString); + + // Scenario 4: Single rail decryption (output should be the same as input) + String encryptedSingleRail = "Single line"; + int singleRailOnly = 1; + String decryptedSingleRail = cipher.decrypt(encryptedSingleRail, singleRailOnly); + assertEquals("Single line", decryptedSingleRail); + } +}