base32Decode function

Uint8List base32Decode(
  1. String input
)

@param input The base32 encoded string to decode.

Implementation

Uint8List base32Decode(String input) {
  try {
    // how many bits we have from the previous character.
    int skip = 0;
    // current byte we're producing.
    int byte = 0;

    var output = Uint8List(((input.length * 4) / 3).ceil() | 0);
    int o = 0;

    final Map<String, int> lookupTable = alphabet
        .split('')
        .fold<Map<String, int>>({},
            (Map<String, int> previousValue, String element) {
      previousValue[element] = alphabet.indexOf(element);
      return previousValue;
    });
    // Add aliases for rfc4648.
    lookupTable
      ..putIfAbsent('0', () => lookupTable['o']!)
      ..putIfAbsent('1', () => lookupTable['i']!);

    void decodeChar(String char) {
      try {
        // Consume a character from the stream, store
        // the output in this.output. As before, better
        // to use update().
        var found = lookupTable[char.toLowerCase()];
        assert(found != null, "Invalid character: $char");
        var val = found!;
        // move to the high bits
        val <<= 3;
        // 32 bit shift?
        byte |= (val & 0xffffffff) >> skip;

        skip += 5;

        if (skip >= 8) {
          // We have enough bytes to produce an output
          output[o++] = byte;
          skip -= 8;

          if (skip > 0) {
            byte = (val << (5 - skip)) & 255;
          } else {
            byte = 0;
          }
        }
      } catch (e) {
        rethrow;
      }
    }

    for (var i = 0; i < input.length; i += 1) {
      decodeChar(input[i]);
    }
    return output.sublist(0, o);
  } catch (e) {
    rethrow;
  }
}