Commit inicial
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
"""Codec para UTF-7 modificado (RFC 3501), usado por IMAP para nombres de carpetas."""
|
||||
|
||||
import base64
|
||||
|
||||
_B64_CHARS = "-,ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+"
|
||||
|
||||
|
||||
def encode(name: str) -> bytes:
|
||||
"""Codifica un nombre de carpeta Unicode a UTF-7 modificado (IMAP)."""
|
||||
res = []
|
||||
buffer = []
|
||||
|
||||
def flush():
|
||||
if not buffer:
|
||||
return
|
||||
raw = "".join(buffer).encode("utf-16-be")
|
||||
b64 = base64.b64encode(raw).decode("ascii").rstrip("=")
|
||||
b64 = b64.replace("/", ",")
|
||||
res.append("&" + b64 + "-")
|
||||
buffer.clear()
|
||||
|
||||
for ch in name:
|
||||
code = ord(ch)
|
||||
if ch == "&":
|
||||
flush()
|
||||
res.append("&-")
|
||||
elif 0x20 <= code <= 0x7E:
|
||||
flush()
|
||||
res.append(ch)
|
||||
else:
|
||||
buffer.append(ch)
|
||||
flush()
|
||||
return "".join(res).encode("ascii")
|
||||
|
||||
|
||||
def decode(data: bytes) -> str:
|
||||
"""Decodifica un nombre de carpeta IMAP en UTF-7 modificado a texto Unicode."""
|
||||
s = data.decode("ascii")
|
||||
res = []
|
||||
i = 0
|
||||
n = len(s)
|
||||
while i < n:
|
||||
ch = s[i]
|
||||
if ch == "&":
|
||||
end = s.find("-", i + 1)
|
||||
if end == -1:
|
||||
end = n
|
||||
segment = s[i + 1:end]
|
||||
if segment == "":
|
||||
res.append("&")
|
||||
else:
|
||||
segment = segment.replace(",", "/")
|
||||
padding = "=" * (-len(segment) % 4)
|
||||
raw = base64.b64decode(segment + padding)
|
||||
res.append(raw.decode("utf-16-be"))
|
||||
i = end + 1
|
||||
else:
|
||||
res.append(ch)
|
||||
i += 1
|
||||
return "".join(res)
|
||||
Reference in New Issue
Block a user