Show More
@@ -0,0 +1,84 b'' | |||||
|
1 | # base85.py: pure python base85 codec | |||
|
2 | # | |||
|
3 | # Copyright (C) 2009 Brendan Cully <brendan@kublai.com> | |||
|
4 | # | |||
|
5 | # This software may be used and distributed according to the terms of | |||
|
6 | # the GNU General Public License, incorporated herein by reference. | |||
|
7 | ||||
|
8 | import struct | |||
|
9 | ||||
|
10 | _b85chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ | |||
|
11 | "abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~" | |||
|
12 | _b85dec = {} | |||
|
13 | ||||
|
14 | def _mkb85dec(): | |||
|
15 | for i in range(len(_b85chars)): | |||
|
16 | _b85dec[_b85chars[i]] = i | |||
|
17 | ||||
|
18 | def b85encode(text, pad=False): | |||
|
19 | """encode text in base85 format""" | |||
|
20 | l = len(text) | |||
|
21 | r = l % 4 | |||
|
22 | if r: | |||
|
23 | text += '\0' * (4 - r) | |||
|
24 | longs = len(text) >> 2 | |||
|
25 | out = [] | |||
|
26 | words = struct.unpack('>%dL' % (longs), text) | |||
|
27 | for word in words: | |||
|
28 | # unrolling improved speed by 33% | |||
|
29 | word, r = divmod(word, 85) | |||
|
30 | e = _b85chars[r] | |||
|
31 | word, r = divmod(word, 85) | |||
|
32 | d = _b85chars[r] | |||
|
33 | word, r = divmod(word, 85) | |||
|
34 | c = _b85chars[r] | |||
|
35 | word, r = divmod(word, 85) | |||
|
36 | b = _b85chars[r] | |||
|
37 | word, r = divmod(word, 85) | |||
|
38 | a = _b85chars[r] | |||
|
39 | ||||
|
40 | out += (a, b, c, d, e) | |||
|
41 | ||||
|
42 | out = ''.join(out) | |||
|
43 | if pad: | |||
|
44 | return out | |||
|
45 | ||||
|
46 | # Trim padding | |||
|
47 | olen = l % 4 | |||
|
48 | if olen: | |||
|
49 | olen += 1 | |||
|
50 | olen += l / 4 * 5 | |||
|
51 | return out[:olen] | |||
|
52 | ||||
|
53 | def b85decode(text): | |||
|
54 | """decode base85-encoded text""" | |||
|
55 | if not _b85dec: | |||
|
56 | _mkb85dec() | |||
|
57 | ||||
|
58 | l = len(text) | |||
|
59 | out = [] | |||
|
60 | for i in range(0, len(text), 5): | |||
|
61 | chunk = text[i:i+5] | |||
|
62 | acc = 0 | |||
|
63 | for j in range(len(chunk)): | |||
|
64 | try: | |||
|
65 | acc = acc * 85 + _b85dec[chunk[j]] | |||
|
66 | except KeyError: | |||
|
67 | raise TypeError('Bad base85 character at byte %d' % (i + j)) | |||
|
68 | if acc > 4294967295: | |||
|
69 | raise OverflowError('Base85 overflow in hunk starting at byte %d' % i) | |||
|
70 | out.append(acc) | |||
|
71 | ||||
|
72 | # Pad final chunk if necessary | |||
|
73 | cl = l % 5 | |||
|
74 | if cl: | |||
|
75 | acc *= 85 ** (5 - cl) | |||
|
76 | if cl > 1: | |||
|
77 | acc += 0xffffff >> (cl - 2) * 8 | |||
|
78 | out[-1] = acc | |||
|
79 | ||||
|
80 | out = struct.pack('>%dL' % (len(out)), *out) | |||
|
81 | if cl: | |||
|
82 | out = out[:-(5 - cl)] | |||
|
83 | ||||
|
84 | return out |
General Comments 0
You need to be logged in to leave comments.
Login now