Peter’s blog ✴ Week 386 ✴ 10 August 2026
THE WEEKLY CHALLENGE
Hitting the bases with recurring numbers
You are given a string representing a number, and an integer specifying the base of that representation. Write a function to convert this string to a decimal integer.
For bases greater than 10, use characters A-Z, a-z, + and / in that order.
Example 1 Input: $num = '101010', $base = 2 Output: 42 Example 2 Input: $num = 'EEADEE', $base = 16 Output: 15642094 Example 3 Input: $num = '755', $base = 8 Output: 493 Example 4 Input: $num = '1BRJB', $base = 36 Output: 2228519 Example 5 Input: $num = '7MyqL', $base = 64 Output: 123456789
My algorithm is to process each digit, left to right,
multiply the result so far (or 1 if none) by $base, and add the value
of the current digit. And that's the answer.
There are a couple of necessary sanity checks: firstly that the
base is between 2 and 64 (because we have been given only 64
characters to use), and secondly that
the each character in the supplied number evaluates to no more
than $base - 1 - so eg for base 10, the maximum digit is 9.
I haven't dealt with negative integers or base 1 numbers; and
integers in large bases (eg 64) quickly exceed Perl's maximum
integer so you'd need Math::BigInt to handle those properly.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge/386/1 use v5.26; # The Weekly Challenge - 2026-08-10 use utf8; # Week 386 - task 1 - Reverse base use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; reverse_base('101010', 2); reverse_base('EEADEE', 16); reverse_base('755', 8); reverse_base('1BRJB', 36); reverse_base('7MyqL', 64); reverse_base('TheWeeklyChallenge', 62); reverse_base('', 44); reverse_base('11111', 1); reverse_base('181', 8); reverse_base('-', 10); sub reverse_base { my ($string, $base, $j, $c, %values, $decimal, $rest, $digit); # initialise ($string, $base) = @_; say qq[\nInput: \$number = '$string', \$base = $base]; unless ($base > 1 and $base < 65) { say qq[Output: base must be between 2 and 64]; return; } # build values table $j = 0; for $c ('0' .. '9', 'A' .. 'Z', 'a' .. 'z', '+', '/') { $values{$c} = $j ++; } # convert string to decimal $decimal = 0; while ($string ne '') { ($digit, $rest) = $string =~ m|^(.)(.*)$|g; if (not defined $values{$digit} or $values{$digit} >= $base) { say qq[Output: invalid digit '$digit']; return; } $decimal = $decimal * $base + $values{$digit}; $string = $rest; } say qq[Output: $decimal base 10]; }
17 lines of code
Input: $number = '101010', $base = 2 Output: 42 base 10 Input: $number = 'EEADEE', $base = 16 Output: 15642094 base 10 Input: $number = '755', $base = 8 Output: 493 base 10 Input: $number = '1BRJB', $base = 36 Output: 2228519 base 10 Input: $number = '7MyqL', $base = 64 Output: 123456789 base 10 Input: $number = 'TheWeeklyChallenge', $base = 62 Output: 8.77960529197082e+31 base 10 Input: $number = '', $base = 44 Output: 0 base 10 Input: $number = '11111', $base = 1 Output: base must be between 2 and 64 Input: $number = '181', $base = 8 Output: invalid digit '8' Input: $number = '-', $base = 10 Output: invalid digit '-'
Any content of this website which has been created by Peter Campbell Smith is in the public domain