FastBase58DecodingAlphabet function
Implementation
List<int> FastBase58DecodingAlphabet(String str, Alphabet alphabet) {
if (str.isEmpty) {
throw Base58Exception('zero length string');
}
var zero = alphabet.encode[0];
var b58sz = str.length;
var zcount = 0;
for (var i = 0; i < b58sz && str.runes.toList()[i] == zero; i++) {
zcount++;
}
var c = 0; // u64
var t = 0;
// the 32bit algo stretches the result up to 2 times
var binu = List<int>.filled(2 * ((b58sz * 406 ~/ 555) + 1), 0); // list<byte>
var outi = List<int>.filled((b58sz + 3) >> 2, 0); // list<uint32>
str.runes.forEach((int r) {
if (r > 127) {
throw Base58Exception('high-bit set on invalid digit');
}
if (alphabet.decode[r] == -1) {
throw Base58Exception('invalid base58 digit' + String.fromCharCode(r));
}
c = alphabet.decode[r];
for (var j = outi.length - 1; j >= 0; j--) {
// Add if cond to avoid overflow
if (support64) {
t = outi[j] * 58 + c;
c = t >> 32;
outi[j] = t & 0xffffffff;
} else {
t = outi[j] * 58 + c;
c = (outi[j] * 58 + c) ~/ 0xffffffff;
outi[j] = t & 0xffffffff;
}
}
});
var mask = ((b58sz % 4) * 8) & 0xffffffff;
if (mask == 0) {
mask = 32;
}
mask = (mask - 8) & 0xffffffff;
var outLen = 0;
for (var j = 0; j < outi.length; j++) {
for (; mask < 32;) {
// loop relies on uint overflow
binu[outLen] = (outi[j] >> mask) & 0xff;
mask = (mask - 8) & 0xffffffff;
outLen++;
}
mask = 24;
}
// find the most significant byte post-decode, if any
for (var msb = zcount; msb < binu.length; msb++) {
if (binu[msb] > 0) {
return binu.sublist(msb - zcount, outLen);
}
}
// it's all zeroes
return binu.sublist(0, outLen);
}