in src/math/compute.php [38:89]
function base_convert(string $value, int $from_base, int $to_base): string {
invariant(
$value !== '',
'Unexpected empty string, expected number in base %d',
$from_base,
);
invariant(
$from_base >= 2 && $from_base <= 36,
'Expected $from_base to be between 2 and 36, got %d',
$from_base,
);
invariant(
$to_base >= 2 && $to_base <= 36,
'Expected $to_base to be between 2 and 36, got %d',
$to_base,
);
invariant(\bcscale(0) === true, 'Unexpected bcscale failure');
$from_alphabet = Str\slice(ALPHABET_ALPHANUMERIC, 0, $from_base);
$result_decimal = '0';
$place_value = \bcpow((string)$from_base, (string)(Str\length($value) - 1));
foreach (Str\chunk($value) as $digit) {
$digit_numeric = Str\search_ci($from_alphabet, $digit);
invariant(
$digit_numeric !== null,
'Invalid digit %s in base %d',
$digit,
$from_base,
);
$result_decimal = \bcadd(
$result_decimal,
\bcmul((string)$digit_numeric, $place_value),
);
$place_value = \bcdiv((string)$place_value, (string)$from_base);
}
if ($to_base === 10) {
return $result_decimal;
}
$to_alphabet = Str\slice(ALPHABET_ALPHANUMERIC, 0, $to_base);
$result = '';
do {
$result = $to_alphabet[\bcmod($result_decimal, (string)$to_base)].$result;
$result_decimal = \bcdiv((string)$result_decimal, (string)$to_base);
} while (\bccomp($result_decimal, '0') > 0);
return $result;
}