1importbase64 2importunicodedata 3frombinasciiimportErrorasBinasciiError 4 5fromplain.internalimportinternalcode 6 7 8@internalcode 9defurlsafe_base64_encode(s):10"""11 Encode a bytestring to a base64 string for use in URLs. Strip any trailing12 equal signs.13 """14returnbase64.urlsafe_b64encode(s).rstrip(b"\n=").decode("ascii")151617@internalcode18defurlsafe_base64_decode(s):19"""20 Decode a base64 encoded string. Add back any trailing equal signs that21 might have been stripped.22 """23s=s.encode()24try:25returnbase64.urlsafe_b64decode(s.ljust(len(s)+len(s)%4,b"="))26except(LookupError,BinasciiError)ase:27raiseValueError(e)282930@internalcode31defunicode_ci_compare(s1,s2):32"""33 Perform case-insensitive comparison of two identifiers, using the34 recommended algorithm from Unicode Technical Report 36, section35 2.11.2(B)(2).36 """37return(38unicodedata.normalize("NFKC",s1).casefold()39==unicodedata.normalize("NFKC",s2).casefold()40)