You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bazarr/libs/itsdangerous/encoding.py

55 lines
1.4 KiB

5 years ago
import base64
import string
import struct
import typing as _t
5 years ago
from .exc import BadData
_t_str_bytes = _t.Union[str, bytes]
5 years ago
def want_bytes(
s: _t_str_bytes, encoding: str = "utf-8", errors: str = "strict"
) -> bytes:
if isinstance(s, str):
5 years ago
s = s.encode(encoding, errors)
5 years ago
return s
def base64_encode(string: _t_str_bytes) -> bytes:
5 years ago
"""Base64 encode a string of bytes or text. The resulting bytes are
safe to use in URLs.
"""
string = want_bytes(string)
return base64.urlsafe_b64encode(string).rstrip(b"=")
def base64_decode(string: _t_str_bytes) -> bytes:
5 years ago
"""Base64 decode a URL-safe string of bytes or text. The result is
bytes.
"""
string = want_bytes(string, encoding="ascii", errors="ignore")
string += b"=" * (-len(string) % 4)
try:
return base64.urlsafe_b64decode(string)
except (TypeError, ValueError):
raise BadData("Invalid base64-encoded data")
# The alphabet used by base64.urlsafe_*
_base64_alphabet = f"{string.ascii_letters}{string.digits}-_=".encode("ascii")
5 years ago
_int64_struct = struct.Struct(">Q")
_int_to_bytes = _int64_struct.pack
_bytes_to_int = _t.cast("_t.Callable[[bytes], _t.Tuple[int]]", _int64_struct.unpack)
5 years ago
def int_to_bytes(num: int) -> bytes:
5 years ago
return _int_to_bytes(num).lstrip(b"\x00")
def bytes_to_int(bytestr: bytes) -> int:
5 years ago
return _bytes_to_int(bytestr.rjust(8, b"\x00"))[0]