| 196 | return bytes(encoded) |
| 197 | |
| 198 | def _b32decode(alphabet, s, casefold=False, map01=None): |
| 199 | # Delay the initialization of the table to not waste memory |
| 200 | # if the function is never called |
| 201 | if alphabet not in _b32rev: |
| 202 | _b32rev[alphabet] = {v: k for k, v in enumerate(alphabet)} |
| 203 | s = _bytes_from_decode_data(s) |
| 204 | if len(s) % 8: |
| 205 | raise binascii.Error('Incorrect padding') |
| 206 | # Handle section 2.4 zero and one mapping. The flag map01 will be either |
| 207 | # False, or the character to map the digit 1 (one) to. It should be |
| 208 | # either L (el) or I (eye). |
| 209 | if map01 is not None: |
| 210 | map01 = _bytes_from_decode_data(map01) |
| 211 | assert len(map01) == 1, repr(map01) |
| 212 | s = s.translate(bytes.maketrans(b'01', b'O' + map01)) |
| 213 | if casefold: |
| 214 | s = s.upper() |
| 215 | # Strip off pad characters from the right. We need to count the pad |
| 216 | # characters because this will tell us how many null bytes to remove from |
| 217 | # the end of the decoded string. |
| 218 | l = len(s) |
| 219 | s = s.rstrip(b'=') |
| 220 | padchars = l - len(s) |
| 221 | # Now decode the full quanta |
| 222 | decoded = bytearray() |
| 223 | b32rev = _b32rev[alphabet] |
| 224 | for i in range(0, len(s), 8): |
| 225 | quanta = s[i: i + 8] |
| 226 | acc = 0 |
| 227 | try: |
| 228 | for c in quanta: |
| 229 | acc = (acc << 5) + b32rev[c] |
| 230 | except KeyError: |
| 231 | raise binascii.Error('Non-base32 digit found') from None |
| 232 | decoded += acc.to_bytes(5) # big endian |
| 233 | # Process the last, partial quanta |
| 234 | if l % 8 or padchars not in {0, 1, 3, 4, 6}: |
| 235 | raise binascii.Error('Incorrect padding') |
| 236 | if padchars and decoded: |
| 237 | acc <<= 5 * padchars |
| 238 | last = acc.to_bytes(5) # big endian |
| 239 | leftover = (43 - 5 * padchars) // 8 # 1: 4, 3: 3, 4: 2, 6: 1 |
| 240 | decoded[-5:] = last[:leftover] |
| 241 | return bytes(decoded) |
| 242 | |
| 243 | |
| 244 | def b32encode(s): |