mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-07 01:35:16 +08:00
Refactor AtbashCipher
, add ParameterizedTest
(#5808)
This commit is contained in:
@ -1,68 +1,98 @@
|
|||||||
package com.thealgorithms.ciphers;
|
package com.thealgorithms.ciphers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Atbash cipher is a simple substitution cipher that replaces each letter
|
* The Atbash cipher is a classic substitution cipher that substitutes each letter
|
||||||
* in the alphabet with its reverse.
|
* with its opposite letter in the alphabet.
|
||||||
* For example, 'A' becomes 'Z', 'B' becomes 'Y', and so on. It works
|
*
|
||||||
* identically for both uppercase and lowercase letters.
|
* For example:
|
||||||
* It's a symmetric cipher, meaning applying it twice returns the original text.
|
* - 'A' becomes 'Z', 'B' becomes 'Y', 'C' becomes 'X', and so on.
|
||||||
* Hence, the encrypting and the decrypting functions are identical
|
* - Similarly, 'a' becomes 'z', 'b' becomes 'y', and so on.
|
||||||
* @author https://github.com/Krounosity
|
*
|
||||||
* Learn more: https://en.wikipedia.org/wiki/Atbash
|
* The cipher works identically for both uppercase and lowercase letters.
|
||||||
|
* Non-alphabetical characters remain unchanged in the output.
|
||||||
|
*
|
||||||
|
* This cipher is symmetric, meaning that applying the cipher twice will return
|
||||||
|
* the original text. Therefore, the same function is used for both encryption and decryption.
|
||||||
|
*
|
||||||
|
* <p>Usage Example:</p>
|
||||||
|
* <pre>
|
||||||
|
* AtbashCipher cipher = new AtbashCipher("Hello World!");
|
||||||
|
* String encrypted = cipher.convert(); // Output: "Svool Dliow!"
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author <a href="https://github.com/Krounosity">Krounosity</a>
|
||||||
|
* @see <a href="https://en.wikipedia.org/wiki/Atbash">Atbash Cipher (Wikipedia)</a>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AtbashCipher {
|
public class AtbashCipher {
|
||||||
|
|
||||||
private String toConvert;
|
private String toConvert;
|
||||||
|
|
||||||
// Default constructor.
|
public AtbashCipher() {
|
||||||
AtbashCipher() {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// String setting constructor.
|
/**
|
||||||
AtbashCipher(String str) {
|
* Constructor with a string parameter.
|
||||||
toConvert = str;
|
*
|
||||||
|
* @param str The string to be converted using the Atbash cipher
|
||||||
|
*/
|
||||||
|
public AtbashCipher(String str) {
|
||||||
|
this.toConvert = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
// String getter method.
|
/**
|
||||||
|
* Returns the current string set for conversion.
|
||||||
|
*
|
||||||
|
* @return The string to be converted
|
||||||
|
*/
|
||||||
public String getString() {
|
public String getString() {
|
||||||
return toConvert;
|
return toConvert;
|
||||||
}
|
}
|
||||||
|
|
||||||
// String setter method.
|
/**
|
||||||
|
* Sets the string to be converted using the Atbash cipher.
|
||||||
|
*
|
||||||
|
* @param str The new string to convert
|
||||||
|
*/
|
||||||
public void setString(String str) {
|
public void setString(String str) {
|
||||||
toConvert = str;
|
this.toConvert = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking whether the current character is capital.
|
/**
|
||||||
|
* Checks if a character is uppercase.
|
||||||
|
*
|
||||||
|
* @param ch The character to check
|
||||||
|
* @return {@code true} if the character is uppercase, {@code false} otherwise
|
||||||
|
*/
|
||||||
private boolean isCapital(char ch) {
|
private boolean isCapital(char ch) {
|
||||||
return ch >= 'A' && ch <= 'Z';
|
return ch >= 'A' && ch <= 'Z';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking whether the current character is smallcased.
|
/**
|
||||||
|
* Checks if a character is lowercase.
|
||||||
|
*
|
||||||
|
* @param ch The character to check
|
||||||
|
* @return {@code true} if the character is lowercase, {@code false} otherwise
|
||||||
|
*/
|
||||||
private boolean isSmall(char ch) {
|
private boolean isSmall(char ch) {
|
||||||
return ch >= 'a' && ch <= 'z';
|
return ch >= 'a' && ch <= 'z';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converting text to atbash cipher code or vice versa.
|
/**
|
||||||
|
* Converts the input string using the Atbash cipher.
|
||||||
|
* Alphabetic characters are substituted with their opposite in the alphabet,
|
||||||
|
* while non-alphabetic characters remain unchanged.
|
||||||
|
*
|
||||||
|
* @return The converted string after applying the Atbash cipher
|
||||||
|
*/
|
||||||
public String convert() {
|
public String convert() {
|
||||||
|
|
||||||
// Using StringBuilder to store new string.
|
|
||||||
StringBuilder convertedString = new StringBuilder();
|
StringBuilder convertedString = new StringBuilder();
|
||||||
|
|
||||||
// Iterating for each character.
|
|
||||||
for (char ch : toConvert.toCharArray()) {
|
for (char ch : toConvert.toCharArray()) {
|
||||||
|
|
||||||
// If the character is smallcased.
|
|
||||||
if (isSmall(ch)) {
|
if (isSmall(ch)) {
|
||||||
convertedString.append((char) ('z' - (ch - 'a')));
|
convertedString.append((char) ('z' - (ch - 'a')));
|
||||||
}
|
} else if (isCapital(ch)) {
|
||||||
// If the character is capital cased.
|
|
||||||
else if (isCapital(ch)) {
|
|
||||||
convertedString.append((char) ('Z' - (ch - 'A')));
|
convertedString.append((char) ('Z' - (ch - 'A')));
|
||||||
}
|
} else {
|
||||||
// Non-alphabetical character.
|
|
||||||
else {
|
|
||||||
convertedString.append(ch);
|
convertedString.append(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,27 +2,42 @@ package com.thealgorithms.ciphers;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import java.util.stream.Stream;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
public class AtbashTest {
|
public class AtbashTest {
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void atbashEncrypt() {
|
@MethodSource("cipherTestProvider")
|
||||||
AtbashCipher normalToEncrypt = new AtbashCipher("Hello World! 123, @cipher abcDEF ZYX 987 madam zzZ Palindrome!");
|
public void testAtbashCipher(String input, String expected) {
|
||||||
String expectedText = "Svool Dliow! 123, @xrksvi zyxWVU ABC 987 nzwzn aaA Kzormwilnv!";
|
AtbashCipher cipher = new AtbashCipher(input);
|
||||||
|
assertEquals(expected, cipher.convert());
|
||||||
normalToEncrypt.setString(normalToEncrypt.convert());
|
|
||||||
|
|
||||||
assertEquals(expectedText, normalToEncrypt.getString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private static Stream<Arguments> cipherTestProvider() {
|
||||||
public void atbashDecrypt() {
|
return Stream.of(
|
||||||
AtbashCipher encryptToNormal = new AtbashCipher("Svool Dliow! 123, @xrksvi zyxWVU ABC 987 nzwzn aaA Kzormwilnv!");
|
// Basic tests with lowercase and uppercase
|
||||||
String expectedText = "Hello World! 123, @cipher abcDEF ZYX 987 madam zzZ Palindrome!";
|
Arguments.of("Hello", "Svool"), Arguments.of("WORLD", "DLIOW"),
|
||||||
|
|
||||||
encryptToNormal.setString(encryptToNormal.convert());
|
// Mixed case with spaces and punctuation
|
||||||
|
Arguments.of("Hello World!", "Svool Dliow!"), Arguments.of("123 ABC xyz", "123 ZYX cba"),
|
||||||
|
|
||||||
assertEquals(expectedText, encryptToNormal.getString());
|
// Palindromes and mixed cases
|
||||||
|
Arguments.of("madam", "nzwzn"), Arguments.of("Palindrome", "Kzormwilnv"),
|
||||||
|
|
||||||
|
// Non-alphabetic characters should remain unchanged
|
||||||
|
Arguments.of("@cipher 123!", "@xrksvi 123!"), Arguments.of("no-change", "ml-xszmtv"),
|
||||||
|
|
||||||
|
// Empty string and single characters
|
||||||
|
Arguments.of("", ""), Arguments.of("A", "Z"), Arguments.of("z", "a"),
|
||||||
|
|
||||||
|
// Numbers and symbols
|
||||||
|
Arguments.of("!@#123", "!@#123"),
|
||||||
|
|
||||||
|
// Full sentence with uppercase, lowercase, symbols, and numbers
|
||||||
|
Arguments.of("Hello World! 123, @cipher abcDEF ZYX 987 madam zzZ Palindrome!", "Svool Dliow! 123, @xrksvi zyxWVU ABC 987 nzwzn aaA Kzormwilnv!"),
|
||||||
|
Arguments.of("Svool Dliow! 123, @xrksvi zyxWVU ABC 987 nzwzn aaA Kzormwilnv!", "Hello World! 123, @cipher abcDEF ZYX 987 madam zzZ Palindrome!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user