Skip to content

Commit d9c5423

Browse files
authored
Merge branch 'master' into int_to_rom_improve
2 parents 5da59b3 + 0feb416 commit d9c5423

File tree

65 files changed

+3002
-525
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3002
-525
lines changed

DIRECTORY.md

Lines changed: 24 additions & 0 deletions
Large diffs are not rendered by default.

pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<dependency>
2121
<groupId>org.junit</groupId>
2222
<artifactId>junit-bom</artifactId>
23-
<version>5.11.2</version>
23+
<version>5.11.3</version>
2424
<type>pom</type>
2525
<scope>import</scope>
2626
</dependency>
@@ -31,7 +31,7 @@
3131
<dependency>
3232
<groupId>org.junit.jupiter</groupId>
3333
<artifactId>junit-jupiter</artifactId>
34-
<version>5.11.2</version>
34+
<version>5.11.3</version>
3535
<scope>test</scope>
3636
</dependency>
3737
<dependency>
@@ -51,7 +51,7 @@
5151
<dependency>
5252
<groupId>org.junit.jupiter</groupId>
5353
<artifactId>junit-jupiter-api</artifactId>
54-
<version>5.11.2</version>
54+
<version>5.11.3</version>
5555
<scope>test</scope>
5656
</dependency>
5757
<dependency>
@@ -132,7 +132,7 @@
132132
<plugin>
133133
<groupId>com.github.spotbugs</groupId>
134134
<artifactId>spotbugs-maven-plugin</artifactId>
135-
<version>4.8.6.4</version>
135+
<version>4.8.6.5</version>
136136
<configuration>
137137
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>
138138
<includeTests>true</includeTests>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* The Baconian Cipher is a substitution cipher where each letter is represented
8+
* by a group of five binary digits (A's and B's). It can also be used to hide
9+
* messages within other texts, making it a simple form of steganography.
10+
* https://en.wikipedia.org/wiki/Bacon%27s_cipher
11+
*
12+
* @author Bennybebo
13+
*/
14+
public class BaconianCipher {
15+
16+
private static final Map<Character, String> BACONIAN_MAP = new HashMap<>();
17+
private static final Map<String, Character> REVERSE_BACONIAN_MAP = new HashMap<>();
18+
19+
static {
20+
// Initialize the Baconian cipher mappings
21+
String[] baconianAlphabet = {"AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", "BABAA", "BABAB", "BABBA", "BABBB", "BBAAA", "BBAAB"};
22+
char letter = 'A';
23+
for (String code : baconianAlphabet) {
24+
BACONIAN_MAP.put(letter, code);
25+
REVERSE_BACONIAN_MAP.put(code, letter);
26+
letter++;
27+
}
28+
29+
// Handle I/J as the same letter
30+
BACONIAN_MAP.put('I', BACONIAN_MAP.get('J'));
31+
REVERSE_BACONIAN_MAP.put(BACONIAN_MAP.get('I'), 'I');
32+
}
33+
34+
/**
35+
* Encrypts the given plaintext using the Baconian cipher.
36+
*
37+
* @param plaintext The plaintext message to encrypt.
38+
* @return The ciphertext as a binary (A/B) sequence.
39+
*/
40+
public String encrypt(String plaintext) {
41+
StringBuilder ciphertext = new StringBuilder();
42+
plaintext = plaintext.toUpperCase().replaceAll("[^A-Z]", ""); // Remove non-letter characters
43+
44+
for (char letter : plaintext.toCharArray()) {
45+
ciphertext.append(BACONIAN_MAP.get(letter));
46+
}
47+
48+
return ciphertext.toString();
49+
}
50+
51+
/**
52+
* Decrypts the given ciphertext encoded in binary (A/B) format using the Baconian cipher.
53+
*
54+
* @param ciphertext The ciphertext to decrypt.
55+
* @return The decrypted plaintext message.
56+
*/
57+
public String decrypt(String ciphertext) {
58+
StringBuilder plaintext = new StringBuilder();
59+
60+
for (int i = 0; i < ciphertext.length(); i += 5) {
61+
String code = ciphertext.substring(i, i + 5);
62+
if (REVERSE_BACONIAN_MAP.containsKey(code)) {
63+
plaintext.append(REVERSE_BACONIAN_MAP.get(code));
64+
} else {
65+
throw new IllegalArgumentException("Invalid Baconian code: " + code);
66+
}
67+
}
68+
69+
return plaintext.toString();
70+
}
71+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import java.math.BigInteger;
4+
5+
public final class DiffieHellman {
6+
7+
private final BigInteger base;
8+
private final BigInteger secret;
9+
private final BigInteger prime;
10+
11+
// Constructor to initialize base, secret, and prime
12+
public DiffieHellman(BigInteger base, BigInteger secret, BigInteger prime) {
13+
// Check for non-null and positive values
14+
if (base == null || secret == null || prime == null || base.signum() <= 0 || secret.signum() <= 0 || prime.signum() <= 0) {
15+
throw new IllegalArgumentException("Base, secret, and prime must be non-null and positive values.");
16+
}
17+
this.base = base;
18+
this.secret = secret;
19+
this.prime = prime;
20+
}
21+
22+
// Method to calculate public value (g^x mod p)
23+
public BigInteger calculatePublicValue() {
24+
// Returns g^x mod p
25+
return base.modPow(secret, prime);
26+
}
27+
28+
// Method to calculate the shared secret key (otherPublic^secret mod p)
29+
public BigInteger calculateSharedSecret(BigInteger otherPublicValue) {
30+
if (otherPublicValue == null || otherPublicValue.signum() <= 0) {
31+
throw new IllegalArgumentException("Other public value must be non-null and positive.");
32+
}
33+
// Returns b^x mod p or a^y mod p
34+
return otherPublicValue.modPow(secret, prime);
35+
}
36+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.thealgorithms.ciphers;
2+
3+
public final class MonoAlphabetic {
4+
5+
private MonoAlphabetic() {
6+
throw new UnsupportedOperationException("Utility class");
7+
}
8+
9+
// Encryption method
10+
public static String encrypt(String data, String key) {
11+
if (!data.matches("[A-Z]+")) {
12+
throw new IllegalArgumentException("Input data contains invalid characters. Only uppercase A-Z are allowed.");
13+
}
14+
StringBuilder sb = new StringBuilder();
15+
16+
// Encrypt each character
17+
for (char c : data.toCharArray()) {
18+
int idx = charToPos(c); // Get the index of the character
19+
sb.append(key.charAt(idx)); // Map to the corresponding character in the key
20+
}
21+
return sb.toString();
22+
}
23+
24+
// Decryption method
25+
public static String decrypt(String data, String key) {
26+
StringBuilder sb = new StringBuilder();
27+
28+
// Decrypt each character
29+
for (char c : data.toCharArray()) {
30+
int idx = key.indexOf(c); // Find the index of the character in the key
31+
if (idx == -1) {
32+
throw new IllegalArgumentException("Input data contains invalid characters.");
33+
}
34+
sb.append(posToChar(idx)); // Convert the index back to the original character
35+
}
36+
return sb.toString();
37+
}
38+
39+
// Helper method: Convert a character to its position in the alphabet
40+
private static int charToPos(char c) {
41+
return c - 'A'; // Subtract 'A' to get position (0 for A, 1 for B, etc.)
42+
}
43+
44+
// Helper method: Convert a position in the alphabet to a character
45+
private static char posToChar(int pos) {
46+
return (char) (pos + 'A'); // Add 'A' to convert position back to character
47+
}
48+
}

src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,28 @@
22

33
import java.util.Map;
44

5+
/**
6+
* A utility class to convert integers to their English word representation.
7+
*
8+
* <p>The class supports conversion of numbers from 0 to 2,147,483,647
9+
* (the maximum value of a 32-bit signed integer). It divides the number
10+
* into groups of three digits (thousands, millions, billions, etc.) and
11+
* translates each group into words.</p>
12+
*
13+
* <h2>Example Usage</h2>
14+
* <pre>
15+
* IntegerToEnglish.integerToEnglishWords(12345);
16+
* // Output: "Twelve Thousand Three Hundred Forty Five"
17+
* </pre>
18+
*
19+
* <p>This class uses two maps:</p>
20+
* <ul>
21+
* <li>BASE_NUMBERS_MAP: Holds English words for numbers 0-20, multiples of 10 up to 90, and 100.</li>
22+
* <li>THOUSAND_POWER_MAP: Maps powers of 1000 (e.g., Thousand, Million, Billion).</li>
23+
* </ul>
24+
*/
525
public final class IntegerToEnglish {
26+
627
private static final Map<Integer, String> BASE_NUMBERS_MAP = Map.ofEntries(Map.entry(0, ""), Map.entry(1, "One"), Map.entry(2, "Two"), Map.entry(3, "Three"), Map.entry(4, "Four"), Map.entry(5, "Five"), Map.entry(6, "Six"), Map.entry(7, "Seven"), Map.entry(8, "Eight"), Map.entry(9, "Nine"),
728
Map.entry(10, "Ten"), Map.entry(11, "Eleven"), Map.entry(12, "Twelve"), Map.entry(13, "Thirteen"), Map.entry(14, "Fourteen"), Map.entry(15, "Fifteen"), Map.entry(16, "Sixteen"), Map.entry(17, "Seventeen"), Map.entry(18, "Eighteen"), Map.entry(19, "Nineteen"), Map.entry(20, "Twenty"),
829
Map.entry(30, "Thirty"), Map.entry(40, "Forty"), Map.entry(50, "Fifty"), Map.entry(60, "Sixty"), Map.entry(70, "Seventy"), Map.entry(80, "Eighty"), Map.entry(90, "Ninety"), Map.entry(100, "Hundred"));
@@ -13,43 +34,53 @@ private IntegerToEnglish() {
1334
}
1435

1536
/**
16-
converts numbers < 1000 to english words
37+
* Converts numbers less than 1000 into English words.
38+
*
39+
* @param number the integer value (0-999) to convert
40+
* @return the English word representation of the input number
1741
*/
1842
private static String convertToWords(int number) {
1943
int remainder = number % 100;
20-
21-
String result;
44+
StringBuilder result = new StringBuilder();
2245

2346
if (remainder <= 20) {
24-
result = BASE_NUMBERS_MAP.get(remainder);
47+
result.append(BASE_NUMBERS_MAP.get(remainder));
2548
} else if (BASE_NUMBERS_MAP.containsKey(remainder)) {
26-
result = BASE_NUMBERS_MAP.get(remainder);
49+
result.append(BASE_NUMBERS_MAP.get(remainder));
2750
} else {
2851
int tensDigit = remainder / 10;
2952
int onesDigit = remainder % 10;
30-
31-
result = String.format("%s %s", BASE_NUMBERS_MAP.get(tensDigit * 10), BASE_NUMBERS_MAP.get(onesDigit));
53+
String tens = BASE_NUMBERS_MAP.getOrDefault(tensDigit * 10, "");
54+
String ones = BASE_NUMBERS_MAP.getOrDefault(onesDigit, "");
55+
result.append(tens);
56+
if (ones != null && !ones.isEmpty()) {
57+
result.append(" ").append(ones);
58+
}
3259
}
3360

3461
int hundredsDigit = number / 100;
35-
3662
if (hundredsDigit > 0) {
37-
result = String.format("%s %s%s", BASE_NUMBERS_MAP.get(hundredsDigit), BASE_NUMBERS_MAP.get(100), result.isEmpty() ? "" : " " + result);
63+
if (result.length() > 0) {
64+
result.insert(0, " ");
65+
}
66+
result.insert(0, String.format("%s Hundred", BASE_NUMBERS_MAP.get(hundredsDigit)));
3867
}
3968

40-
return result;
69+
return result.toString().trim();
4170
}
4271

4372
/**
44-
Only convert groups of three digit if they are non-zero
73+
* Converts a non-negative integer to its English word representation.
74+
*
75+
* @param number the integer to convert (0-2,147,483,647)
76+
* @return the English word representation of the input number
4577
*/
4678
public static String integerToEnglishWords(int number) {
4779
if (number == 0) {
4880
return "Zero";
4981
}
5082

5183
StringBuilder result = new StringBuilder();
52-
5384
int index = 0;
5485

5586
while (number > 0) {
@@ -58,23 +89,20 @@ public static String integerToEnglishWords(int number) {
5889

5990
if (remainder > 0) {
6091
String subResult = convertToWords(remainder);
61-
6292
if (!subResult.isEmpty()) {
63-
if (!result.isEmpty()) {
64-
result.insert(0, subResult + " " + THOUSAND_POWER_MAP.get(index) + " ");
65-
} else {
66-
if (index > 0) {
67-
result = new StringBuilder(subResult + " " + THOUSAND_POWER_MAP.get(index));
68-
} else {
69-
result = new StringBuilder(subResult);
70-
}
93+
if (index > 0) {
94+
subResult += " " + THOUSAND_POWER_MAP.get(index);
95+
}
96+
if (result.length() > 0) {
97+
result.insert(0, " ");
7198
}
99+
result.insert(0, subResult);
72100
}
73101
}
74102

75103
index++;
76104
}
77105

78-
return result.toString();
106+
return result.toString().trim();
79107
}
80108
}

src/main/java/com/thealgorithms/conversions/OctalToBinary.java

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,40 @@
11
package com.thealgorithms.conversions;
22

33
/**
4-
* Converts any Octal Number to a Binary Number
4+
* A utility class to convert an octal (base-8) number into its binary (base-2) representation.
5+
*
6+
* <p>This class provides methods to:
7+
* <ul>
8+
* <li>Convert an octal number to its binary equivalent</li>
9+
* <li>Convert individual octal digits to binary</li>
10+
* </ul>
11+
*
12+
* <h2>Octal to Binary Conversion:</h2>
13+
* <p>An octal number is converted to binary by converting each octal digit to its 3-bit binary equivalent.
14+
* The result is a long representing the full binary equivalent of the octal number.</p>
15+
*
16+
* <h2>Example Usage</h2>
17+
* <pre>
18+
* long binary = OctalToBinary.convertOctalToBinary(52); // Output: 101010 (52 in octal is 101010 in binary)
19+
* </pre>
520
*
621
* @author Bama Charan Chhandogi
22+
* @see <a href="https://en.wikipedia.org/wiki/Octal">Octal Number System</a>
23+
* @see <a href="https://en.wikipedia.org/wiki/Binary_number">Binary Number System</a>
724
*/
8-
925
public final class OctalToBinary {
1026
private OctalToBinary() {
1127
}
28+
29+
/**
30+
* Converts an octal number to its binary representation.
31+
*
32+
* <p>Each octal digit is individually converted to its 3-bit binary equivalent, and the binary
33+
* digits are concatenated to form the final binary number.</p>
34+
*
35+
* @param octalNumber the octal number to convert (non-negative integer)
36+
* @return the binary equivalent as a long
37+
*/
1238
public static long convertOctalToBinary(int octalNumber) {
1339
long binaryNumber = 0;
1440
int digitPosition = 1;
@@ -20,12 +46,25 @@ public static long convertOctalToBinary(int octalNumber) {
2046
binaryNumber += binaryDigit * digitPosition;
2147

2248
octalNumber /= 10;
23-
digitPosition *= 1000; // Move to the next group of 3 binary digits
49+
digitPosition *= 1000;
2450
}
2551

2652
return binaryNumber;
2753
}
2854

55+
/**
56+
* Converts a single octal digit (0-7) to its binary equivalent.
57+
*
58+
* <p>For example:
59+
* <ul>
60+
* <li>Octal digit 7 is converted to binary 111</li>
61+
* <li>Octal digit 3 is converted to binary 011</li>
62+
* </ul>
63+
* </p>
64+
*
65+
* @param octalDigit a single octal digit (0-7)
66+
* @return the binary equivalent as a long
67+
*/
2968
public static long convertOctalDigitToBinary(int octalDigit) {
3069
long binaryDigit = 0;
3170
int binaryMultiplier = 1;

0 commit comments

Comments
 (0)