Skip to content
Open
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
16 changes: 14 additions & 2 deletions ciphers/des_ecb.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
Expand All @@ -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.
Expand All @@ -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__":
Expand Down
24 changes: 24 additions & 0 deletions tests/test_des_unicode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import pytest

from ciphers.des_ecb import Des


@pytest.mark.parametrize(
"text",
[
"Hello",
"Hello \u20ac",
"\u65e5\u672c\u8a9e",
"r\u00e9sum\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