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.

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