Skip to content

Commit 21db250

Browse files
author
Nihhaar Saini
committed
Add One-Time Pad Cipher implementation
1 parent 1c6026e commit 21db250

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import java.security.SecureRandom;
4+
import java.util.Objects;
5+
6+
public final class OneTimePadCipher {
7+
8+
private static final SecureRandom RANDOM = new SecureRandom();
9+
10+
private OneTimePadCipher() {}
11+
12+
public static byte[] generateKey(final int length) {
13+
if (length <= 0) {
14+
throw new IllegalArgumentException("Key length must be positive");
15+
}
16+
byte[] key = new byte[length];
17+
RANDOM.nextBytes(key);
18+
return key;
19+
}
20+
21+
public static byte[] encrypt(final byte[] plaintext, final byte[] key) {
22+
Objects.requireNonNull(plaintext, "plaintext");
23+
Objects.requireNonNull(key, "key");
24+
25+
if (plaintext.length != key.length) {
26+
throw new IllegalArgumentException("Plaintext and key must have the same length");
27+
}
28+
29+
byte[] ciphertext = new byte[plaintext.length];
30+
for (int i = 0; i < plaintext.length; i++) {
31+
ciphertext[i] = (byte) (plaintext[i] ^ key[i]);
32+
}
33+
return ciphertext;
34+
}
35+
36+
public static byte[] decrypt(final byte[] ciphertext, final byte[] key) {
37+
return encrypt(ciphertext, key);
38+
}
39+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.nio.charset.StandardCharsets;
6+
import org.junit.Test;
7+
8+
public class OneTimePadCipherTest {
9+
10+
@Test
11+
public void encryptDecryptWorks() {
12+
String original = "OTP Test ";
13+
byte[] plaintext = original.getBytes(StandardCharsets.UTF_8);
14+
byte[] key = OneTimePadCipher.generateKey(plaintext.length);
15+
16+
byte[] encrypted = OneTimePadCipher.encrypt(plaintext, key);
17+
byte[] decrypted = OneTimePadCipher.decrypt(encrypted, key);
18+
19+
assertEquals(original, new String(decrypted, StandardCharsets.UTF_8));
20+
}
21+
22+
@Test(expected = IllegalArgumentException.class)
23+
public void throwsIfDifferentLength() {
24+
byte[] plaintext = "Hi".getBytes(StandardCharsets.UTF_8);
25+
byte[] key = new byte[] { 1, 2, 3 }; // wrong length
26+
27+
OneTimePadCipher.encrypt(plaintext, key);
28+
}
29+
}

0 commit comments

Comments
 (0)