v0.166.0
 1import base64
 2import unicodedata
 3from binascii import Error as BinasciiError
 4
 5
 6def urlsafe_base64_encode(s: bytes) -> str:
 7    """
 8    Encode a bytestring to a base64 string for use in URLs. Strip any trailing
 9    equal signs.
10    """
11    return base64.urlsafe_b64encode(s).rstrip(b"\n=").decode("ascii")
12
13
14def urlsafe_base64_decode(s: str) -> bytes:
15    """
16    Decode a base64 encoded string. Add back any trailing equal signs that
17    might have been stripped.
18    """
19    s_bytes = s.encode()
20    try:
21        return base64.urlsafe_b64decode(
22            s_bytes.ljust(len(s_bytes) + len(s_bytes) % 4, b"=")
23        )
24    except (LookupError, BinasciiError) as e:
25        raise ValueError(e)
26
27
28def unicode_ci_compare(s1: str, s2: str) -> bool:
29    """
30    Perform case-insensitive comparison of two identifiers, using the
31    recommended algorithm from Unicode Technical Report 36, section
32    2.11.2(B)(2).
33    """
34    return (
35        unicodedata.normalize("NFKC", s1).casefold()
36        == unicodedata.normalize("NFKC", s2).casefold()
37    )