forked from dhondta/python-codext
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbase45.py
More file actions
84 lines (70 loc) · 2.71 KB
/
Copy pathbase45.py
File metadata and controls
84 lines (70 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# -*- coding: UTF-8 -*-
"""Base45 Codec - base45 content encoding.
This codec:
- en/decodes strings from str to str
- en/decodes strings from bytes to bytes
- decodes file content to str (read)
- encodes file content from str to bytes (write)
"""
from ._base import _get_charset, digits, lower, main, upper
from ..__common__ import *
__examples__ = {
'enc(base45|base-45|base_45)': {'this is a test!': "AWE+EDH44.OEOCC7WE QEX0"},
'enc(base45-inv|base_45_inv)': {'this is a test!': "K6O+ONREE.YOYMMH6O 0O7A"},
'dec(base45)': {'BAD STRING\00': None, 'AWE+EDH44.OEOCC7WE QEX000': None},
}
__guess__ = ["base45", "base45-inv"]
B45 = {
'': digits + upper + " $%*+-./:",
'[-_]inv(?:erted)?$': upper + digits + " $%*+-./:",
}
__chr = lambda c: chr(c >> 8) + chr(c & 0xff) if isinstance(c, int) and 256 <= c <= 65535 else \
chr(c) if isinstance(c, int) else c
__ord = lambda c: ord(c) if not isinstance(c, int) else c
def base45_encode(mode):
b45 = _get_charset(B45, mode)
def encode(text, errors="strict"):
t, s = b(text), ""
for i in range(0, len(text), 2):
n = 256 * __ord(t[i])
try:
n += __ord(t[i+1])
except IndexError:
n = __ord(t[i])
s += b45[n % 45] + b45[n // 45]
break
m = n // 45**2
n -= m * 45**2
s += b45[n % 45] + b45[n // 45] + b45[m]
return s, len(text)
return encode
def base45_decode(mode):
b45 = {c: i for i, c in enumerate(_get_charset(B45, mode))}
def decode(text, errors="strict"):
t, s = b(text), ""
ehandler = handle_error("base45", errors, decode=True)
for i in range(0, len(text), 3):
try:
n = b45[__chr(t[i])]
except KeyError:
ehandler(__chr(t[i]), i, s)
try:
j = i + 1
n += 45 * b45[__chr(t[j])]
except KeyError:
ehandler(__chr(t[j]), j, s)
except IndexError:
ehandler(__chr(t[i]), i, s)
try:
k = i + 2
n += 45 ** 2 * b45[__chr(t[k])]
except KeyError:
ehandler(__chr(t[k]), k, s)
except IndexError:
s += __chr(n)
continue
s += __chr(n // 256) + __chr(n % 256)
return s, len(text)
return decode
add("base45", base45_encode, base45_decode, r"^base[-_]?45(|[-_]inv(?:erted)?)$", expansion_factor=1.5)
main = main(45, "<https://datatracker.ietf.org/doc/html/draft-faltstrom-base45-04.txt>")