5
5
import java .util .HexFormat ;
6
6
7
7
/**
8
- * A simple implementation of XOR cipher that, given a key, allows to encrypt and decrypt a plaintext.
8
+ * A simple implementation of the XOR cipher that allows both encryption and decryption
9
+ * using a given key. This cipher works by applying the XOR bitwise operation between
10
+ * the bytes of the input text and the corresponding bytes of the key (repeating the key
11
+ * if necessary).
9
12
*
10
- * @author <a href="https://github.com/lcsjunior">lcsjunior</a>
13
+ * Usage:
14
+ * - Encryption: Converts plaintext into a hexadecimal-encoded ciphertext.
15
+ * - Decryption: Converts the hexadecimal ciphertext back into plaintext.
16
+ *
17
+ * Characteristics:
18
+ * - Symmetric: The same key is used for both encryption and decryption.
19
+ * - Simple but vulnerable: XOR encryption is insecure for real-world cryptography,
20
+ * especially when the same key is reused.
21
+ *
22
+ * Example:
23
+ * Plaintext: "Hello!"
24
+ * Key: "key"
25
+ * Encrypted: "27090c03120b"
26
+ * Decrypted: "Hello!"
11
27
*
28
+ * Reference: <a href="https://en.wikipedia.org/wiki/XOR_cipher">XOR Cipher - Wikipedia</a>
29
+ *
30
+ * @author <a href="https://github.com/lcsjunior">lcsjunior</a>
12
31
*/
13
32
public final class XORCipher {
14
33
34
+ // Default character encoding for string conversion
15
35
private static final Charset CS_DEFAULT = StandardCharsets .UTF_8 ;
16
36
17
37
private XORCipher () {
18
38
}
19
39
40
+ /**
41
+ * Applies the XOR operation between the input bytes and the key bytes.
42
+ * If the key is shorter than the input, it wraps around (cyclically).
43
+ *
44
+ * @param inputBytes The input byte array (plaintext or ciphertext).
45
+ * @param keyBytes The key byte array used for XOR operation.
46
+ * @return A new byte array containing the XOR result.
47
+ */
20
48
public static byte [] xor (final byte [] inputBytes , final byte [] keyBytes ) {
21
49
byte [] outputBytes = new byte [inputBytes .length ];
22
50
for (int i = 0 ; i < inputBytes .length ; ++i ) {
@@ -25,14 +53,40 @@ public static byte[] xor(final byte[] inputBytes, final byte[] keyBytes) {
25
53
return outputBytes ;
26
54
}
27
55
56
+ /**
57
+ * Encrypts the given plaintext using the XOR cipher with the specified key.
58
+ * The result is a hexadecimal-encoded string representing the ciphertext.
59
+ *
60
+ * @param plainText The input plaintext to encrypt.
61
+ * @param key The encryption key.
62
+ * @throws IllegalArgumentException if the key is empty.
63
+ * @return A hexadecimal string representing the encrypted text.
64
+ */
28
65
public static String encrypt (final String plainText , final String key ) {
66
+ if (key .isEmpty ()) {
67
+ throw new IllegalArgumentException ("Key must not be empty" );
68
+ }
69
+
29
70
byte [] plainTextBytes = plainText .getBytes (CS_DEFAULT );
30
71
byte [] keyBytes = key .getBytes (CS_DEFAULT );
31
72
byte [] xorResult = xor (plainTextBytes , keyBytes );
32
73
return HexFormat .of ().formatHex (xorResult );
33
74
}
34
75
76
+ /**
77
+ * Decrypts the given ciphertext (in hexadecimal format) using the XOR cipher
78
+ * with the specified key. The result is the original plaintext.
79
+ *
80
+ * @param cipherText The hexadecimal string representing the encrypted text.
81
+ * @param key The decryption key (must be the same as the encryption key).
82
+ * @throws IllegalArgumentException if the key is empty.
83
+ * @return The decrypted plaintext.
84
+ */
35
85
public static String decrypt (final String cipherText , final String key ) {
86
+ if (key .isEmpty ()) {
87
+ throw new IllegalArgumentException ("Key must not be empty" );
88
+ }
89
+
36
90
byte [] cipherBytes = HexFormat .of ().parseHex (cipherText );
37
91
byte [] keyBytes = key .getBytes (CS_DEFAULT );
38
92
byte [] xorResult = xor (cipherBytes , keyBytes );
0 commit comments