| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| import base64 |
| import binascii |
| from abc import ABCMeta, abstractmethod |
| from typing import SupportsBytes, Type |
|
|
|
|
| |
| |
| class _Encoder(metaclass=ABCMeta): |
| @staticmethod |
| @abstractmethod |
| def encode(data: bytes) -> bytes: |
| """Transform raw data to encoded data.""" |
|
|
| @staticmethod |
| @abstractmethod |
| def decode(data: bytes) -> bytes: |
| """Transform encoded data back to raw data. |
| |
| Decoding after encoding should be a no-op, i.e. `decode(encode(x)) == x`. |
| """ |
|
|
|
|
| |
| |
| |
| Encoder = Type[_Encoder] |
|
|
|
|
| class RawEncoder(_Encoder): |
| @staticmethod |
| def encode(data: bytes) -> bytes: |
| return data |
|
|
| @staticmethod |
| def decode(data: bytes) -> bytes: |
| return data |
|
|
|
|
| class HexEncoder(_Encoder): |
| @staticmethod |
| def encode(data: bytes) -> bytes: |
| return binascii.hexlify(data) |
|
|
| @staticmethod |
| def decode(data: bytes) -> bytes: |
| return binascii.unhexlify(data) |
|
|
|
|
| class Base16Encoder(_Encoder): |
| @staticmethod |
| def encode(data: bytes) -> bytes: |
| return base64.b16encode(data) |
|
|
| @staticmethod |
| def decode(data: bytes) -> bytes: |
| return base64.b16decode(data) |
|
|
|
|
| class Base32Encoder(_Encoder): |
| @staticmethod |
| def encode(data: bytes) -> bytes: |
| return base64.b32encode(data) |
|
|
| @staticmethod |
| def decode(data: bytes) -> bytes: |
| return base64.b32decode(data) |
|
|
|
|
| class Base64Encoder(_Encoder): |
| @staticmethod |
| def encode(data: bytes) -> bytes: |
| return base64.b64encode(data) |
|
|
| @staticmethod |
| def decode(data: bytes) -> bytes: |
| return base64.b64decode(data) |
|
|
|
|
| class URLSafeBase64Encoder(_Encoder): |
| @staticmethod |
| def encode(data: bytes) -> bytes: |
| return base64.urlsafe_b64encode(data) |
|
|
| @staticmethod |
| def decode(data: bytes) -> bytes: |
| return base64.urlsafe_b64decode(data) |
|
|
|
|
| class Encodable: |
| def encode(self: SupportsBytes, encoder: Encoder = RawEncoder) -> bytes: |
| return encoder.encode(bytes(self)) |
|
|