From 32ea446800e2334e6042da789c1e9dcea7291af7 Mon Sep 17 00:00:00 2001 From: Dheeraj Kumar <45139709+dheeraj1010@users.noreply.github.com> Date: Tue, 7 Oct 2025 19:23:17 +0000 Subject: [PATCH 1/5] feat(ciphers): Add PermutationCipher implementation with comprehensive tests - Implement PermutationCipher class for transposition encryption/decryption - Add encrypt() and decrypt() methods with permutation key support - Include robust key validation (1-based positions, no duplicates) - Implement automatic padding for incomplete blocks using 'X' character - Add comprehensive error handling with descriptive exceptions - Create 20+ JUnit test cases covering encryption, decryption, edge cases - Support various key sizes and text processing (spaces removal, case handling) - Include detailed JavaDoc documentation with algorithm explanation Algorithm Details: - Divides plaintext into blocks based on key length - Rearranges characters within each block according to permutation positions - Supports round-trip encryption/decryption with inverse permutation - Handles edge cases: empty strings, single character keys, padding Tests include: basic functionality, different key sizes, error validation, real-world examples, and edge case handling. --- .../ciphers/PermutationCipher.java | 197 ++++++++++++ .../ciphers/PermutationCipherTest.java | 293 ++++++++++++++++++ 2 files changed, 490 insertions(+) create mode 100644 src/main/java/com/thealgorithms/ciphers/PermutationCipher.java create mode 100644 src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java diff --git a/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java new file mode 100644 index 000000000000..f822bb081430 --- /dev/null +++ b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java @@ -0,0 +1,197 @@ +package com.thealgorithms.ciphers; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * A Java implementation of Permutation Cipher. + * It is a type of transposition cipher in which the plaintext is divided into blocks + * and the characters within each block are rearranged according to a fixed permutation key. + * + * For example, with key {3, 1, 2} and plaintext "HELLO", the text is divided into blocks + * of 3 characters: "HEL" and "LO" (with padding). The characters are then rearranged + * according to the key positions. + * + * @author GitHub Copilot + */ +public class PermutationCipher { + + private static final char PADDING_CHAR = 'X'; + + /** + * Encrypts the given plaintext using the permutation cipher with the specified key. + * + * @param plaintext the text to encrypt + * @param key the permutation key (array of integers representing positions) + * @return the encrypted text + * @throws IllegalArgumentException if the key is invalid + */ + public String encrypt(String plaintext, int[] key) { + validateKey(key); + + if (plaintext == null || plaintext.isEmpty()) { + return plaintext; + } + + // Remove spaces and convert to uppercase for consistent processing + String cleanText = plaintext.replaceAll("\\s+", "").toUpperCase(); + + // Pad the text to make it divisible by key length + String paddedText = padText(cleanText, key.length); + + StringBuilder encrypted = new StringBuilder(); + + // Process text in blocks of key length + for (int i = 0; i < paddedText.length(); i += key.length) { + String block = paddedText.substring(i, Math.min(i + key.length, paddedText.length())); + encrypted.append(permuteBlock(block, key)); + } + + return encrypted.toString(); + } + + /** + * Decrypts the given ciphertext using the permutation cipher with the specified key. + * + * @param ciphertext the text to decrypt + * @param key the permutation key (array of integers representing positions) + * @return the decrypted text + * @throws IllegalArgumentException if the key is invalid + */ + public String decrypt(String ciphertext, int[] key) { + validateKey(key); + + if (ciphertext == null || ciphertext.isEmpty()) { + return ciphertext; + } + + // Create the inverse permutation + int[] inverseKey = createInverseKey(key); + + StringBuilder decrypted = new StringBuilder(); + + // Process text in blocks of key length + for (int i = 0; i < ciphertext.length(); i += key.length) { + String block = ciphertext.substring(i, Math.min(i + key.length, ciphertext.length())); + decrypted.append(permuteBlock(block, inverseKey)); + } + + // Remove padding characters from the end + return removePadding(decrypted.toString()); + } + + /** + * Validates that the permutation key is valid. + * A valid key must contain all integers from 1 to n exactly once, where n is the key length. + * + * @param key the permutation key to validate + * @throws IllegalArgumentException if the key is invalid + */ + private void validateKey(int[] key) { + if (key == null || key.length == 0) { + throw new IllegalArgumentException("Key cannot be null or empty"); + } + + Set keySet = new HashSet<>(); + for (int position : key) { + if (position < 1 || position > key.length) { + throw new IllegalArgumentException("Key must contain integers from 1 to " + key.length); + } + if (!keySet.add(position)) { + throw new IllegalArgumentException("Key must contain each position exactly once"); + } + } + } + + /** + * Pads the text with padding characters to make its length divisible by the block size. + * + * @param text the text to pad + * @param blockSize the size of each block + * @return the padded text + */ + private String padText(String text, int blockSize) { + int remainder = text.length() % blockSize; + if (remainder == 0) { + return text; + } + + int paddingNeeded = blockSize - remainder; + StringBuilder padded = new StringBuilder(text); + for (int i = 0; i < paddingNeeded; i++) { + padded.append(PADDING_CHAR); + } + + return padded.toString(); + } + + /** + * Applies the permutation to a single block of text. + * + * @param block the block to permute + * @param key the permutation key + * @return the permuted block + */ + private String permuteBlock(String block, int[] key) { + if (block.length() != key.length) { + // Handle case where block is shorter than key (shouldn't happen with proper padding) + block = padText(block, key.length); + } + + char[] result = new char[key.length]; + char[] blockChars = block.toCharArray(); + + for (int i = 0; i < key.length; i++) { + // Key positions are 1-based, so subtract 1 for 0-based array indexing + result[i] = blockChars[key[i] - 1]; + } + + return new String(result); + } + + /** + * Creates the inverse permutation key for decryption. + * + * @param key the original permutation key + * @return the inverse key + */ + private int[] createInverseKey(int[] key) { + int[] inverse = new int[key.length]; + + for (int i = 0; i < key.length; i++) { + // The inverse key maps each position to where it should go + inverse[key[i] - 1] = i + 1; + } + + return inverse; + } + + /** + * Removes padding characters from the end of the decrypted text. + * + * @param text the text to remove padding from + * @return the text without padding + */ + private String removePadding(String text) { + if (text.isEmpty()) { + return text; + } + + int i = text.length() - 1; + while (i >= 0 && text.charAt(i) == PADDING_CHAR) { + i--; + } + + return text.substring(0, i + 1); + } + + /** + * Gets the padding character used by this cipher. + * + * @return the padding character + */ + public char getPaddingChar() { + return PADDING_CHAR; + } +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java b/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java new file mode 100644 index 000000000000..ad4c3587a4ae --- /dev/null +++ b/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java @@ -0,0 +1,293 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class PermutationCipherTest { + + private final PermutationCipher cipher = new PermutationCipher(); + + @Test + void testBasicEncryption() { + // given + String plaintext = "HELLO"; + int[] key = {3, 1, 2}; // Move 3rd position to 1st, 1st to 2nd, 2nd to 3rd + + // when + String encrypted = cipher.encrypt(plaintext, key); + + // then + // "HELLO" becomes "HEL" + "LOX" (padded) + // "HEL" with key {3,1,2} becomes "LHE" (L=3rd, H=1st, E=2nd) + // "LOX" with key {3,1,2} becomes "XLO" (X=3rd, L=1st, O=2nd) + assertEquals("LHEXLO", encrypted); + } + + @Test + void testBasicDecryption() { + // given + String ciphertext = "LHEXLO"; + int[] key = {3, 1, 2}; + + // when + String decrypted = cipher.decrypt(ciphertext, key); + + // then + assertEquals("HELLO", decrypted); + } + + @Test + void testEncryptDecryptRoundTrip() { + // given + String plaintext = "THIS IS A TEST MESSAGE"; + int[] key = {4, 2, 1, 3}; + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("THISISATESTMESSAGE", decrypted); // Spaces are removed during encryption + } + + @Test + void testSingleCharacterKey() { + // given + String plaintext = "ABCDEF"; + int[] key = {1}; // Identity permutation + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("ABCDEF", encrypted); // Should remain unchanged + assertEquals("ABCDEF", decrypted); + } + + @Test + void testLargerKey() { + // given + String plaintext = "PERMUTATION"; + int[] key = {5, 3, 1, 4, 2}; // 5-character permutation + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("PERMUTATION", decrypted); + } + + @Test + void testExactBlockSize() { + // given + String plaintext = "ABCDEF"; // Length 6, divisible by key length 3 + int[] key = {2, 3, 1}; + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("ABCDEF", decrypted); + } + + @Test + void testEmptyString() { + // given + String plaintext = ""; + int[] key = {2, 1, 3}; + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("", encrypted); + assertEquals("", decrypted); + } + + @Test + void testNullString() { + // given + String plaintext = null; + int[] key = {2, 1, 3}; + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals(null, encrypted); + assertEquals(null, decrypted); + } + + @Test + void testStringWithSpaces() { + // given + String plaintext = "A B C D E F"; + int[] key = {2, 1}; + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("ABCDEF", decrypted); // Spaces should be removed + } + + @Test + void testLowercaseConversion() { + // given + String plaintext = "hello world"; + int[] key = {3, 1, 2}; + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("HELLOWORLD", decrypted); // Should be converted to uppercase + } + + @Test + void testInvalidKeyNull() { + // given + String plaintext = "HELLO"; + int[] key = null; + + // when & then + assertThrows(IllegalArgumentException.class, () -> cipher.encrypt(plaintext, key)); + assertThrows(IllegalArgumentException.class, () -> cipher.decrypt(plaintext, key)); + } + + @Test + void testInvalidKeyEmpty() { + // given + String plaintext = "HELLO"; + int[] key = {}; + + // when & then + assertThrows(IllegalArgumentException.class, () -> cipher.encrypt(plaintext, key)); + assertThrows(IllegalArgumentException.class, () -> cipher.decrypt(plaintext, key)); + } + + @Test + void testInvalidKeyOutOfRange() { + // given + String plaintext = "HELLO"; + int[] key = {1, 2, 4}; // 4 is out of range for key length 3 + + // when & then + assertThrows(IllegalArgumentException.class, () -> cipher.encrypt(plaintext, key)); + assertThrows(IllegalArgumentException.class, () -> cipher.decrypt(plaintext, key)); + } + + @Test + void testInvalidKeyZero() { + // given + String plaintext = "HELLO"; + int[] key = {0, 1, 2}; // 0 is invalid (should be 1-based) + + // when & then + assertThrows(IllegalArgumentException.class, () -> cipher.encrypt(plaintext, key)); + assertThrows(IllegalArgumentException.class, () -> cipher.decrypt(plaintext, key)); + } + + @Test + void testInvalidKeyDuplicate() { + // given + String plaintext = "HELLO"; + int[] key = {1, 2, 2}; // Duplicate position + + // when & then + assertThrows(IllegalArgumentException.class, () -> cipher.encrypt(plaintext, key)); + assertThrows(IllegalArgumentException.class, () -> cipher.decrypt(plaintext, key)); + } + + @Test + void testInvalidKeyMissingPosition() { + // given + String plaintext = "HELLO"; + int[] key = {1, 3}; // Missing position 2 + + // when & then + assertThrows(IllegalArgumentException.class, () -> cipher.encrypt(plaintext, key)); + assertThrows(IllegalArgumentException.class, () -> cipher.decrypt(plaintext, key)); + } + + @Test + void testReverseKey() { + // given + String plaintext = "ABCD"; + int[] key = {4, 3, 2, 1}; // Reverse order + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("DCBA", encrypted); // Should be reversed + assertEquals("ABCD", decrypted); + } + + @Test + void testSpecificExampleFromDescription() { + // given + String plaintext = "HELLO"; + int[] key = {3, 1, 2}; + + // when + String encrypted = cipher.encrypt(plaintext, key); + + // then + // Block 1: "HEL" -> positions {3,1,2} -> "LHE" + // Block 2: "LOX" -> positions {3,1,2} -> "XLO" + assertEquals("LHEXLO", encrypted); + + // Verify decryption + String decrypted = cipher.decrypt(encrypted, key); + assertEquals("HELLO", decrypted); + } + + @Test + void testPaddingCharacterGetter() { + // when + char paddingChar = cipher.getPaddingChar(); + + // then + assertEquals('X', paddingChar); + } + + @Test + void testLongText() { + // given + String plaintext = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG"; + int[] key = {4, 1, 3, 2}; + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG", decrypted); + } + + @Test + void testIdentityPermutation() { + // given + String plaintext = "IDENTITY"; + int[] key = {1, 2, 3, 4}; // Identity permutation + + // when + String encrypted = cipher.encrypt(plaintext, key); + String decrypted = cipher.decrypt(encrypted, key); + + // then + assertEquals("IDENTITY", encrypted); // Should remain unchanged + assertEquals("IDENTITY", decrypted); + } +} \ No newline at end of file From 1619bdab6d8d4b02b2d12b034ca674e2cdc0310b Mon Sep 17 00:00:00 2001 From: Dheeraj Kumar <45139709+dheeraj1010@users.noreply.github.com> Date: Tue, 7 Oct 2025 19:57:13 +0000 Subject: [PATCH 2/5] Run PermutationCipherTest using Maven --- .../ciphers/PermutationCipherTest.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java b/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java index ad4c3587a4ae..360cdaf4767a 100644 --- a/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java +++ b/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java @@ -290,4 +290,35 @@ void testIdentityPermutation() { assertEquals("IDENTITY", encrypted); // Should remain unchanged assertEquals("IDENTITY", decrypted); } -} \ No newline at end of file + + @Test + void testEmptyStringRemovePadding() { + // given - Test to cover line 178 (empty string case in removePadding) + String ciphertext = ""; + int[] key = {2, 1, 3}; + + // when + String decrypted = cipher.decrypt(ciphertext, key); + + // then + assertEquals("", decrypted); // Should return empty string directly + } + + @Test + void testBlockShorterThanKey() { + // given - Test to cover line 139 (block length != key length case) + // This is a defensive case where permuteBlock might receive a block shorter than key + // We can test this by manually creating a scenario with malformed ciphertext + String malformedCiphertext = "AB"; // Length 2, but key length is 3 + int[] key = {3, 1, 2}; // Key length is 3 + + // when - This should trigger the padding logic in permuteBlock during decryption + String decrypted = cipher.decrypt(malformedCiphertext, key); + + // then - The method should handle the short block gracefully + // "AB" gets padded to "ABX", then permuted with inverse key {2,3,1} + // inverse key {2,3,1} means: pos 2→1st, pos 3→2nd, pos 1→3rd = "BXA" + // Padding removal only removes trailing X's, so "BXA" remains as is + assertEquals("BXA", decrypted); + } +} From 25545d476c4a62f001916d0ea1c632a4a3719194 Mon Sep 17 00:00:00 2001 From: Dheeraj Kumar <45139709+dheeraj1010@users.noreply.github.com> Date: Tue, 7 Oct 2025 20:04:05 +0000 Subject: [PATCH 3/5] refactor(PermutationCipher): clean up code by removing unnecessary whitespace and comments --- .../ciphers/PermutationCipher.java | 79 +++++++++---------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java index f822bb081430..e08c3cbc5f7c 100644 --- a/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java @@ -1,6 +1,5 @@ package com.thealgorithms.ciphers; -import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -8,20 +7,20 @@ * A Java implementation of Permutation Cipher. * It is a type of transposition cipher in which the plaintext is divided into blocks * and the characters within each block are rearranged according to a fixed permutation key. - * + * * For example, with key {3, 1, 2} and plaintext "HELLO", the text is divided into blocks * of 3 characters: "HEL" and "LO" (with padding). The characters are then rearranged * according to the key positions. - * + * * @author GitHub Copilot */ public class PermutationCipher { - + private static final char PADDING_CHAR = 'X'; - + /** * Encrypts the given plaintext using the permutation cipher with the specified key. - * + * * @param plaintext the text to encrypt * @param key the permutation key (array of integers representing positions) * @return the encrypted text @@ -29,31 +28,31 @@ public class PermutationCipher { */ public String encrypt(String plaintext, int[] key) { validateKey(key); - + if (plaintext == null || plaintext.isEmpty()) { return plaintext; } - + // Remove spaces and convert to uppercase for consistent processing String cleanText = plaintext.replaceAll("\\s+", "").toUpperCase(); - + // Pad the text to make it divisible by key length String paddedText = padText(cleanText, key.length); - + StringBuilder encrypted = new StringBuilder(); - + // Process text in blocks of key length for (int i = 0; i < paddedText.length(); i += key.length) { String block = paddedText.substring(i, Math.min(i + key.length, paddedText.length())); encrypted.append(permuteBlock(block, key)); } - + return encrypted.toString(); } - + /** * Decrypts the given ciphertext using the permutation cipher with the specified key. - * + * * @param ciphertext the text to decrypt * @param key the permutation key (array of integers representing positions) * @return the decrypted text @@ -61,30 +60,29 @@ public String encrypt(String plaintext, int[] key) { */ public String decrypt(String ciphertext, int[] key) { validateKey(key); - + if (ciphertext == null || ciphertext.isEmpty()) { return ciphertext; } - + // Create the inverse permutation int[] inverseKey = createInverseKey(key); - + StringBuilder decrypted = new StringBuilder(); - + // Process text in blocks of key length for (int i = 0; i < ciphertext.length(); i += key.length) { String block = ciphertext.substring(i, Math.min(i + key.length, ciphertext.length())); decrypted.append(permuteBlock(block, inverseKey)); } - + // Remove padding characters from the end return removePadding(decrypted.toString()); } - /** * Validates that the permutation key is valid. * A valid key must contain all integers from 1 to n exactly once, where n is the key length. - * + * * @param key the permutation key to validate * @throws IllegalArgumentException if the key is invalid */ @@ -92,7 +90,7 @@ private void validateKey(int[] key) { if (key == null || key.length == 0) { throw new IllegalArgumentException("Key cannot be null or empty"); } - + Set keySet = new HashSet<>(); for (int position : key) { if (position < 1 || position > key.length) { @@ -103,10 +101,10 @@ private void validateKey(int[] key) { } } } - + /** * Pads the text with padding characters to make its length divisible by the block size. - * + * * @param text the text to pad * @param blockSize the size of each block * @return the padded text @@ -116,19 +114,18 @@ private String padText(String text, int blockSize) { if (remainder == 0) { return text; } - + int paddingNeeded = blockSize - remainder; StringBuilder padded = new StringBuilder(text); for (int i = 0; i < paddingNeeded; i++) { padded.append(PADDING_CHAR); } - + return padded.toString(); } - /** * Applies the permutation to a single block of text. - * + * * @param block the block to permute * @param key the permutation key * @return the permuted block @@ -138,38 +135,38 @@ private String permuteBlock(String block, int[] key) { // Handle case where block is shorter than key (shouldn't happen with proper padding) block = padText(block, key.length); } - + char[] result = new char[key.length]; char[] blockChars = block.toCharArray(); - + for (int i = 0; i < key.length; i++) { // Key positions are 1-based, so subtract 1 for 0-based array indexing result[i] = blockChars[key[i] - 1]; } - + return new String(result); } - + /** * Creates the inverse permutation key for decryption. - * + * * @param key the original permutation key * @return the inverse key */ private int[] createInverseKey(int[] key) { int[] inverse = new int[key.length]; - + for (int i = 0; i < key.length; i++) { // The inverse key maps each position to where it should go inverse[key[i] - 1] = i + 1; } - + return inverse; } - + /** * Removes padding characters from the end of the decrypted text. - * + * * @param text the text to remove padding from * @return the text without padding */ @@ -177,18 +174,18 @@ private String removePadding(String text) { if (text.isEmpty()) { return text; } - + int i = text.length() - 1; while (i >= 0 && text.charAt(i) == PADDING_CHAR) { i--; } - + return text.substring(0, i + 1); } - + /** * Gets the padding character used by this cipher. - * + * * @return the padding character */ public char getPaddingChar() { From afbf7afe6576946f8cc89fe07fadca66292522cd Mon Sep 17 00:00:00 2001 From: Dheeraj Kumar <45139709+dheeraj1010@users.noreply.github.com> Date: Tue, 7 Oct 2025 20:08:59 +0000 Subject: [PATCH 4/5] fix(tests): remove unnecessary whitespace in test assertion for encryption --- src/main/java/com/thealgorithms/ciphers/PermutationCipher.java | 2 +- .../java/com/thealgorithms/ciphers/PermutationCipherTest.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java index e08c3cbc5f7c..ce443545db1d 100644 --- a/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java @@ -191,4 +191,4 @@ private String removePadding(String text) { public char getPaddingChar() { return PADDING_CHAR; } -} \ No newline at end of file +} diff --git a/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java b/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java index 360cdaf4767a..272ec33eec8d 100644 --- a/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java +++ b/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java @@ -246,8 +246,7 @@ void testSpecificExampleFromDescription() { // then // Block 1: "HEL" -> positions {3,1,2} -> "LHE" // Block 2: "LOX" -> positions {3,1,2} -> "XLO" - assertEquals("LHEXLO", encrypted); - + assertEquals("LHEXLO", encrypted); // Verify decryption String decrypted = cipher.decrypt(encrypted, key); assertEquals("HELLO", decrypted); From c1c6b0f76110c0343dbb66d13389bdf3aebecb2d Mon Sep 17 00:00:00 2001 From: Dheeraj Kumar <45139709+dheeraj1010@users.noreply.github.com> Date: Tue, 7 Oct 2025 20:13:23 +0000 Subject: [PATCH 5/5] fix(tests): correct indentation in assertion for encryption verification --- .../java/com/thealgorithms/ciphers/PermutationCipherTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java b/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java index 272ec33eec8d..4ba6787cc97e 100644 --- a/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java +++ b/src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.java @@ -246,7 +246,7 @@ void testSpecificExampleFromDescription() { // then // Block 1: "HEL" -> positions {3,1,2} -> "LHE" // Block 2: "LOX" -> positions {3,1,2} -> "XLO" - assertEquals("LHEXLO", encrypted); + assertEquals("LHEXLO", encrypted); // Verify decryption String decrypted = cipher.decrypt(encrypted, key); assertEquals("HELLO", decrypted);