| 44 | b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~") |
| 45 | |
| 46 | def b85decode(b): |
| 47 | _b85dec = [None] * 256 |
| 48 | for i, c in enumerate(iterbytes(_b85alphabet)): |
| 49 | _b85dec[c] = i |
| 50 | |
| 51 | padding = (-len(b)) % 5 |
| 52 | b = b + b'~' * padding |
| 53 | out = [] |
| 54 | packI = struct.Struct('!I').pack |
| 55 | for i in range(0, len(b), 5): |
| 56 | chunk = b[i:i + 5] |
| 57 | acc = 0 |
| 58 | try: |
| 59 | for c in iterbytes(chunk): |
| 60 | acc = acc * 85 + _b85dec[c] |
| 61 | except TypeError: |
| 62 | for j, c in enumerate(iterbytes(chunk)): |
| 63 | if _b85dec[c] is None: |
| 64 | raise ValueError( |
| 65 | 'bad base85 character at position %d' % (i + j) |
| 66 | ) |
| 67 | raise |
| 68 | try: |
| 69 | out.append(packI(acc)) |
| 70 | except struct.error: |
| 71 | raise ValueError('base85 overflow in hunk starting at byte %d' |
| 72 | % i) |
| 73 | |
| 74 | result = b''.join(out) |
| 75 | if padding: |
| 76 | result = result[:-padding] |
| 77 | return result |
| 78 | |
| 79 | |
| 80 | def bootstrap(tmpdir=None): |