diff --git a/backend/utils/crypto.py b/backend/utils/crypto.py new file mode 100644 index 0000000..9419c33 --- /dev/null +++ b/backend/utils/crypto.py @@ -0,0 +1,38 @@ +def encrypt_bytes(key: int, bs: bytes) -> bytes: + """ + Простое шифрование XOR + модификация ключа. + + Аргументы: + - key: int - начальный ключ + - bs: bytes - данные для шифрования + + Возвращает: + - bytes: зашифрованные данные + """ + result: bytearray = bytearray() + for b in bs: + k: int = (key >> 8) & 0xFF + enc: int = b ^ k + result.append(enc) + key = (enc & key) | 0x482D + return bytes(result) + + +def decrypt_bytes(key: int, bs: bytes) -> bytes: + """ + Обратное преобразование к EncryptBytes. + + Аргументы: + - key: int - начальный ключ + - bs: bytes - данные для расшифровки + + Возвращает: + - bytes: расшифрованные данные + """ + result: bytearray = bytearray() + for b in bs: + k: int = (key >> 8) & 0xFF + dec: int = b ^ k + result.append(dec) + key = (b & key) | 0x482D + return bytes(result) diff --git a/backend/utils/encoding.py b/backend/utils/encoding.py new file mode 100644 index 0000000..9f2cd27 --- /dev/null +++ b/backend/utils/encoding.py @@ -0,0 +1,40 @@ +from typing import Dict + +# Таблица Base64-подобного варианта +VariantBase64Table: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" +VariantBase64Dict: Dict[int, str] = {i: VariantBase64Table[i] for i in range(len(VariantBase64Table))} +VariantBase64ReverseDict: Dict[str, int] = {VariantBase64Table[i]: i for i in range(len(VariantBase64Table))} + + +def variant_base64_encode(bs: bytes) -> bytes: + """ + Пользовательский Base64 encode (малые блоки, little-endian). + + Аргументы: + - bs: bytes - исходные данные + + Возвращает: + - bytes: закодированные данные + """ + result: bytearray = bytearray() + blocks_count, left_bytes = divmod(len(bs), 3) + + # Полные блоки по 3 байта + for i in range(blocks_count): + b: bytes = bs[3*i:3*i+3] + coding_int: int = int.from_bytes(b, "little") + block: str = "".join( + VariantBase64Dict[(coding_int >> shift) & 0x3F] for shift in (0, 6, 12, 18) + ) + result.extend(block.encode("ascii")) + + # Обработка оставшихся байт + if left_bytes: + b: bytes = bs[-left_bytes:] + coding_int: int = int.from_bytes(b, "little") + block: str = "".join( + VariantBase64Dict[(coding_int >> shift) & 0x3F] for shift in range(0, left_bytes*8 + 1, 6) + ) + result.extend(block.encode("ascii")) + + return bytes(result)