-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuucoder.py
More file actions
82 lines (70 loc) · 2.3 KB
/
uucoder.py
File metadata and controls
82 lines (70 loc) · 2.3 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
class UUCoder:
@staticmethod
def encode(barr):
rtn = []
len_barr = len(barr)
read = 0
stop = False
offset = 0
while not stop:
left = len_barr - read
if left == 0:
stop = True
b = left if left <= 45 else 45
rtn.append(UUCoder._enc(b))
for i in range(0, b, 3):
if len_barr - offset < 3:
padding = bytearray(3)
for z in range(len_barr - offset):
padding[z] = barr[offset + z]
UUCoder.encode_bytes(padding, 0, rtn)
else:
UUCoder.encode_bytes(barr, offset, rtn)
offset += 3
rtn.append('\n')
read += b
if b < 45:
stop = True
return ''.join(rtn)
@staticmethod
def decode(str):
out = bytearray(len(str))
len_out = 0
offset = 0
stop = False
it = iter(str)
while not stop:
b = UUCoder._dec(next(it))
b1 = next(it)
if b > 45:
raise ValueError(f"can't decode string [{str}]")
if b < 45:
stop = True
len_out += b
while b > 0:
UUCoder.decode_chars(it, out, offset, b1)
b1 = next(it, None)
offset += 3
b -= 3
return bytes(out[:len_out])
@staticmethod
def encode_bytes(in_bytes, off, out):
out.append(UUCoder._enc(in_bytes[off] >> 2))
out.append(UUCoder._enc((in_bytes[off] << 4 & 0x30) | (in_bytes[off + 1] >> 4 & 0xf)))
out.append(UUCoder._enc((in_bytes[off + 1] << 2 & 0x3c) | (in_bytes[off + 2] >> 6 & 3)))
out.append(UUCoder._enc(in_bytes[off + 2] & 0x3f))
@staticmethod
def decode_chars(it, out, off, b1):
b1 = UUCoder._dec(b1)
b2 = UUCoder._dec(next(it))
b3 = UUCoder._dec(next(it))
b4 = UUCoder._dec(next(it))
out[off] = (b1 << 2 | b2 >> 4) & 0xff
out[off + 1] = (b2 << 4 | b3 >> 2) & 0xff
out[off + 2] = (b3 << 6 | b4) & 0xff
@staticmethod
def _enc(c):
return chr((c & 0x3f) + 32)
@staticmethod
def _dec(c):
return (ord(c) - 32) & 0x3f