Декодер base64
This commit is contained in:
48
backend/utils/encoding.py
Normal file
48
backend/utils/encoding.py
Normal file
@@ -0,0 +1,48 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user