## Map the numbers, 0 .. 36 to the symbols we use
## to represent the number in base37
my @c1 = (' ', '0'..'9', 'A'..'Z' );
sub fromB37 {
my $n = shift; ## Get the number to convert
## Allocate space for the Base37 representation
## Initialise it to the representation of 0 (six spaces)
my $s = ' ';
## For each position in the string
for( 0 .. 5 ) {
## extract the next base37 digit value
## look up its representaion character
## and assign it to the 'right place' i the string.
substr( $s, $_, 1 ) = $c1[ $n%37 ] );
## dividing by 37 effectively right-shifts
## the last digit's value out of the number
$n /= 37;
}
$s;
}
my @c2;
## Map the ordinal values of the symbols
## to their numeric values (0 .. 37)
## The sparse array is faster than a hash
$c2[ ord( $c1[ $_ ] ) ] = $_ for 0 .. 36;
sub toB37 {
my $n = 0; ## initialise our return value to 0
## split the base37 representation
## into a list of the ordinal values of the symbols
## and reverse their order to match that produced by fromB37()
for( reverse unpack 'C*', $_[0] ) {
## multiple the running total by 37
## (effectively left-shifting the accumulator
## to accommodate the next digit.)
## and add value of the next base37 digit
## by looking it up in the mapping array
$n = $n * 37 + $c2[ $_ ];
}
## return the accumulated value.
$n;
}