Peter’s blog ✴ Week 386 ✴ 10 August 2026

THE WEEKLY CHALLENGE
Hitting the bases with recurring numbers

The Perl Camel

Task 1

Reverse base

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.

Examples


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

Analysis

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.

Perl Weekly’s review

from PW issue 786

In week 386, Peter presents a neat, efficient, and very strong Perl design for the base conversion process. The blog post is remarkable because there is an insightful mention of the special cases, and all the edge cases are taken into account, for example, the digit limits and base limits, which makes it different from the others.

This review may cover either or both challenges for this week.

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Your input:



eg: BEAD



eg: 16

Script


#!/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

Output from script


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