From b76f2ea20886a18e632c15dd7297b773f3796693 Mon Sep 17 00:00:00 2001 From: Mohammed Anas Zakir Husain Nakhuda Date: Sun, 25 Oct 2026 19:27:32 -0300 Subject: [PATCH 1/2] Fix Unicode text handling in DES encryption --- ciphers/des_ecb.py | 16 ++++++++++++++-- tests/test_des_unicode.py | 24 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/test_des_unicode.py diff --git a/ciphers/des_ecb.py b/ciphers/des_ecb.py index 559aee9b764a..caa969cf239e 100644 --- a/ciphers/des_ecb.py +++ b/ciphers/des_ecb.py @@ -474,6 +474,8 @@ def encrypt(key: str, input_string: str) -> str: """ Encrypts a given input string using the DES encryption algorithm. + The input text is encoded as UTF-8 before encryption. + Args: key (str): A 16-character hexadecimal string representing a 64-bit key. input_string (str): The plain text string to be encrypted. @@ -488,7 +490,9 @@ def encrypt(key: str, input_string: str) -> str: >>> encrypted # Checking the cipher to ensure consistency 'c84e3c8fb646872720b224896db4f60' """ - plain_bitset = Operations.string_to_bitset(input_string) + plain_bitset = [ + bit for byte in input_string.encode("utf-8") for bit in format(byte, "08b") + ] padded_bitset = Operations.pad_right_to_multiple_of_n(plain_bitset, 64) keys = Des.key_schedule(key) cipher_bitset = Des.des(keys, padded_bitset) @@ -499,6 +503,10 @@ def decrypt(key: str, cipher_text: str) -> str: """ Decrypts the given cipher text using DES decryption. + The decrypted bytes are decoded as UTF-8. + Ciphertext generated using the previous character-based encoding + may not be compatible with this implementation. + Args: key (str): A 16-character hexadecimal string representing a 64-bit key. cipher_text (str): A hexadecimal string representing the encrypted data. @@ -516,7 +524,11 @@ def decrypt(key: str, cipher_text: str) -> str: cipher_bitset = Operations.hex_to_bitset(cipher_text, 64) keys = Des.key_schedule(key)[::-1] plain_bitset = Des.des(keys, cipher_bitset) - return Operations.bitset_to_string(plain_bitset).replace("\x00", "") + plain_bytes = bytes( + int("".join(plain_bitset[i : i + 8]), 2) + for i in range(0, len(plain_bitset), 8) + ) + return plain_bytes.rstrip(b"\x00").decode("utf-8") if __name__ == "__main__": diff --git a/tests/test_des_unicode.py b/tests/test_des_unicode.py new file mode 100644 index 000000000000..c5a2de6dcee5 --- /dev/null +++ b/tests/test_des_unicode.py @@ -0,0 +1,24 @@ +import pytest + +from ciphers.des_ecb import Des + + +@pytest.mark.parametrize( + "text", + [ + "Hello", + "Hello \u20ac", + "\u65e5\u672c\u8a9e", + "caf\u00e9", + "Hello \u20ac!", + "\U0001f600", + "1234567\u20ac", + "abc\x00def", + ], +) +def test_des_unicode_round_trip(text: str) -> None: + key = "133457799BBCDFF1" + encrypted = Des.encrypt(key, text) + decrypted = Des.decrypt(key, encrypted) + + assert decrypted == text From b7a7005db0ac36f0acfa39bc390edf5d522349aa Mon Sep 17 00:00:00 2001 From: Mohammed Anas Zakir Husain Nakhuda Date: Sun, 25 Oct 2026 19:46:14 -0300 Subject: [PATCH 2/2] Fix spelling check in Unicode regression tests --- tests/test_des_unicode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_des_unicode.py b/tests/test_des_unicode.py index c5a2de6dcee5..37212a604a28 100644 --- a/tests/test_des_unicode.py +++ b/tests/test_des_unicode.py @@ -9,7 +9,7 @@ "Hello", "Hello \u20ac", "\u65e5\u672c\u8a9e", - "caf\u00e9", + "r\u00e9sum\u00e9", "Hello \u20ac!", "\U0001f600", "1234567\u20ac",