Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.thealgorithms.ciphers;

import java.security.SecureRandom;

/**
* The One-Time Pad Cipher is a symmetric encryption technique
* that XORs plaintext with a truly random key of equal length.
*
* ⚠️ Important:
* - The key must be random and used only once.
* - Key reuse makes it insecure.
*
* Example:
* Plaintext: HELLO
* Key: XMCKL
* Ciphertext: EQNVZ
*
* Reference:
* Shannon, C. E. (1949). Communication Theory of Secrecy Systems.
*/
public class OneTimePadCipher {

private static final SecureRandom RANDOM = new SecureRandom();

/**
* Encrypts or decrypts a message using the One-Time Pad method.
*
* @param input The input string (plaintext or ciphertext)
* @param key The key (must be the same length as input)
* @return The resulting encrypted/decrypted string
*/
public static String xorCipher(String input, String key) {
if (input.length() != key.length()) {
throw new IllegalArgumentException("Input and key lengths must match!");
}

StringBuilder output = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char encryptedChar = (char) (input.charAt(i) ^ key.charAt(i));
output.append(encryptedChar);
}
return output.toString();
}

/**
* Generates a random key of the same length as the message.
*
* @param length The desired key length
* @return A random key string
*/
public static String generateRandomKey(int length) {
StringBuilder key = new StringBuilder();
for (int i = 0; i < length; i++) {
// Generate printable ASCII range (32–126)
key.append((char) (RANDOM.nextInt(95) + 32));
}
return key.toString();
}

public static void main(String[] args) {
String message = "HELLO WORLD";
String key = generateRandomKey(message.length());

String encrypted = xorCipher(message, key);
String decrypted = xorCipher(encrypted, key);

System.out.println("Message: " + message);
System.out.println("Key: " + key);
System.out.println("Encrypted: " + encrypted);
System.out.println("Decrypted: " + decrypted);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.thealgorithms.ciphers;

import java.security.SecureRandom;

/**
* Implementation of the One-Time Pad Cipher.
*
* <p>The One-Time Pad Cipher is a symmetric encryption technique that XORs
* plaintext with a truly random key of equal length. It is considered
* theoretically unbreakable when the key is random, used only once, and kept
* secret.
*
* <p>Example:
*
* <pre>
* Plaintext: HELLO
* Key: XMCKL
* Ciphertext: EQNVZ
* </pre>
*
* @see <a href="https://en.wikipedia.org/wiki/One-time_pad">Wikipedia: One-time pad</a>
*/
public final class OneTimePadCipher {

private static final SecureRandom RANDOM = new SecureRandom();

private OneTimePadCipher() {
// Utility class; prevent instantiation.
}

/**
* Encrypts or decrypts a message using the One-Time Pad method.
*
* @param input the input string (plaintext or ciphertext)
* @param key the key (must be the same length as input)
* @return the resulting encrypted/decrypted string
* @throws IllegalArgumentException if input and key lengths do not match
*/
public static String xorCipher(String input, String key) {
if (input.length() != key.length()) {
throw new IllegalArgumentException("Input and key lengths must match!");
}

StringBuilder output = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char encryptedChar = (char) (input.charAt(i) ^ key.charAt(i));
output.append(encryptedChar);
}
return output.toString();
}

/**
* Generates a random key of the same length as the message.
*
* @param length the desired key length
* @return a random key string
*/
public static String generateRandomKey(int length) {
StringBuilder key = new StringBuilder();
for (int i = 0; i < length; i++) {
// Generate printable ASCII range (32–126)
key.append((char) (RANDOM.nextInt(95) + 32));
}
return key.toString();
}
}
Loading