Mercurial > hg
annotate mercurial/pure/base85.py @ 7961:52e442fe43f4
convert: Add testcase for convert authormap.
author | Marti Raudsepp <marti@juffo.org> |
---|---|
date | Sat, 14 Mar 2009 14:31:08 +0200 |
parents | 3ac7114c2555 |
children | 46293a0c7e9f |
rev | line source |
---|---|
7701 | 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!#$%&()*+-;<=>?@^_`{|}~" | |
7835
2505e9f84153
Optimization of pure.base85.b85encode
Mads Kiilerich <mads@kiilerich.com>
parents:
7701
diff
changeset
|
12 _b85chars2 = [(a + b) for a in _b85chars for b in _b85chars] |
7701 | 13 _b85dec = {} |
14 | |
15 def _mkb85dec(): | |
16 for i in range(len(_b85chars)): | |
17 _b85dec[_b85chars[i]] = i | |
18 | |
19 def b85encode(text, pad=False): | |
20 """encode text in base85 format""" | |
21 l = len(text) | |
22 r = l % 4 | |
23 if r: | |
24 text += '\0' * (4 - r) | |
25 longs = len(text) >> 2 | |
26 words = struct.unpack('>%dL' % (longs), text) | |
27 | |
7881
3ac7114c2555
kill another trailing space
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7835
diff
changeset
|
28 out = ''.join(_b85chars[(word / 52200625) % 85] + |
7835
2505e9f84153
Optimization of pure.base85.b85encode
Mads Kiilerich <mads@kiilerich.com>
parents:
7701
diff
changeset
|
29 _b85chars2[(word / 7225) % 7225] + |
2505e9f84153
Optimization of pure.base85.b85encode
Mads Kiilerich <mads@kiilerich.com>
parents:
7701
diff
changeset
|
30 _b85chars2[word % 7225] |
2505e9f84153
Optimization of pure.base85.b85encode
Mads Kiilerich <mads@kiilerich.com>
parents:
7701
diff
changeset
|
31 for word in words) |
7701 | 32 |
33 if pad: | |
34 return out | |
35 | |
36 # Trim padding | |
37 olen = l % 4 | |
38 if olen: | |
39 olen += 1 | |
40 olen += l / 4 * 5 | |
41 return out[:olen] | |
42 | |
43 def b85decode(text): | |
44 """decode base85-encoded text""" | |
45 if not _b85dec: | |
46 _mkb85dec() | |
47 | |
48 l = len(text) | |
49 out = [] | |
50 for i in range(0, len(text), 5): | |
51 chunk = text[i:i+5] | |
52 acc = 0 | |
53 for j in range(len(chunk)): | |
54 try: | |
55 acc = acc * 85 + _b85dec[chunk[j]] | |
56 except KeyError: | |
57 raise TypeError('Bad base85 character at byte %d' % (i + j)) | |
58 if acc > 4294967295: | |
59 raise OverflowError('Base85 overflow in hunk starting at byte %d' % i) | |
60 out.append(acc) | |
61 | |
62 # Pad final chunk if necessary | |
63 cl = l % 5 | |
64 if cl: | |
65 acc *= 85 ** (5 - cl) | |
66 if cl > 1: | |
67 acc += 0xffffff >> (cl - 2) * 8 | |
68 out[-1] = acc | |
69 | |
70 out = struct.pack('>%dL' % (len(out)), *out) | |
71 if cl: | |
72 out = out[:-(5 - cl)] | |
73 | |
74 return out |