diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 9c906c381608..42e8f54eb7fd 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -1,45 +1,60 @@
-name: "Bug report"
-description: "Create a report to help us improve"
-title: "[BUG]
"
+name: Bug Report
+description: Report an issue to help us improve
+title: "Provide a brief, clear description of the bug"
labels: ["bug"]
+
body:
- - type: textarea
- id: description
+ - type: input
+ id: summary
+ attributes:
+ label: Summary
+ description: Brief description of the issue.
+
+ - type: dropdown
+ id: environment
attributes:
- label: "Description"
- description: "A clear and concise description of what the bug is."
- validations:
- required: true
+ label: Operating System
+ options:
+ - Windows
+ - macOS
+ - Linux
+ - Other
+
- type: textarea
id: steps
attributes:
- label: "Steps to reproduce"
- description: "Steps to reproduce the behavior (if applicable)"
+ label: Steps to Reproduce
+ description: How can we reproduce this bug?
placeholder: |
- 1. Go to '...'
- 2. Click on '....'
- 3. Scroll down to '....'
- 4. See error
- validations:
- required: false
+ 1. Step one
+ 2. Step two
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected Behavior
+ placeholder: What should have happened?
+
+ - type: textarea
+ id: actual
+ attributes:
+ label: Actual Behavior
+ placeholder: What actually happened?
+
- type: textarea
- id: exceptedbhv
+ id: logs
attributes:
- label: "Excepted behavior"
- description: "A clear and concise description of what you expected to happen."
- validations:
- required: true
+ label: Logs / Error Messages
+ placeholder: Paste any relevant logs or screenshots.
+
- type: textarea
- id: screenshots
+ id: config
attributes:
- label: "Screenshots"
- description: "If applicable, add screenshots to help explain your problem."
- validations:
- required: false
+ label: Configuration Files
+ description: VS Code settings.json / other configs if applicable.
+
- type: textarea
id: context
attributes:
- label: "Additional context"
- description: "Is there anything else we should know about this bug report?"
- validations:
- required: false
+ label: Additional Context
+ placeholder: Any other info?
diff --git a/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java b/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java
new file mode 100644
index 000000000000..66ff2b513b80
--- /dev/null
+++ b/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java
@@ -0,0 +1,39 @@
+package com.thealgorithms.ciphers;
+
+import java.security.SecureRandom;
+import java.util.Objects;
+
+public final class OneTimePadCipher {
+
+ private static final SecureRandom RANDOM = new SecureRandom();
+
+ private OneTimePadCipher() {}
+
+ public static byte[] generateKey(final int length) {
+ if (length <= 0) {
+ throw new IllegalArgumentException("Key length must be positive");
+ }
+ byte[] key = new byte[length];
+ RANDOM.nextBytes(key);
+ return key;
+ }
+
+ public static byte[] encrypt(final byte[] plaintext, final byte[] key) {
+ Objects.requireNonNull(plaintext, "plaintext");
+ Objects.requireNonNull(key, "key");
+
+ if (plaintext.length != key.length) {
+ throw new IllegalArgumentException("Plaintext and key must have the same length");
+ }
+
+ byte[] ciphertext = new byte[plaintext.length];
+ for (int i = 0; i < plaintext.length; i++) {
+ ciphertext[i] = (byte) (plaintext[i] ^ key[i]);
+ }
+ return ciphertext;
+ }
+
+ public static byte[] decrypt(final byte[] ciphertext, final byte[] key) {
+ return encrypt(ciphertext, key);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/ciphers/OneTimePadCipherTest.java b/src/test/java/com/thealgorithms/ciphers/OneTimePadCipherTest.java
new file mode 100644
index 000000000000..e1c11de12690
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/OneTimePadCipherTest.java
@@ -0,0 +1,33 @@
+package com.thealgorithms.ciphers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.nio.charset.StandardCharsets;
+import org.junit.jupiter.api.Test;
+
+public class OneTimePadCipherTest {
+
+ @Test
+ public void encryptDecryptWorks() {
+ String original = "OTP Test";
+ byte[] plaintext = original.getBytes(StandardCharsets.UTF_8);
+ byte[] key = OneTimePadCipher.generateKey(plaintext.length);
+
+ byte[] encrypted = OneTimePadCipher.encrypt(plaintext, key);
+ byte[] decrypted = OneTimePadCipher.decrypt(encrypted, key);
+
+ assertEquals(original, new String(decrypted, StandardCharsets.UTF_8));
+ }
+
+ @Test
+ public void throwsIfDifferentLength() {
+ byte[] plaintext = "Hi".getBytes(StandardCharsets.UTF_8);
+ byte[] key = new byte[] {1, 2, 3};
+
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> OneTimePadCipher.encrypt(plaintext, key)
+ );
+ }
+}