# A Binary-Octal-Decimal-Hexadecimal-Base36 converter

Intended Audience
Prerequisites
The Converter form
The Converter code
- Input-Output operations
- Decimal to String conversion
- String to Decimal conversion
Summary
Amendment History
Comments

## Intended Audience

This tutorial is intended for developers who wish to have a utility which will quickly enable them to convert values from one number format to another. Although PHP has a series of standard functions to convert values between decimal (base 10) and binary (base 2), octal (base 8) and hexadecimal (base 16) and back again, this tutorial will show you how to build a single routine that can process other number systems such as Base 36.

## Prerequisites

Access to a working PHP development environment. No special modules are required as this script uses only standard PHP functions. A basic knowledge of PHP and HTML is assumed. This exercise will help you construct a PHP script with the following characteristics:

• It is a self-contained, self-executing script.
• It has multiple input fields.
• It has multiple submit buttons.
• It has some simple validation which may cause an error message to be displayed.
• It uses some basic string manipulation and mathematical functions.

## The Converter form

The finished script will produce a form that looks like the following in your browser: To convert from decimal to another format do the following:

• Enter the decimal number in the box labelled 'Decimal (input)'.
• Press one of the 'DEC to xxx' buttons to have the converted number appear in the associated text box.

To convert from another format to decimal do the following:

• Enter the number in the box against the relevant label.
• Press the associated 'xxx to DEC' button to have the converted number appear in the 'Decimal (output)' box.

You can run the program from here and view the complete source code from here.

## The Converter code

In the following code snippets I shall ignore most of the HTML code as it should be self-explanatory. I will however give explanations for each piece of PHP code.

### Input-Output operations

This first piece of code looks for input. When the program is first requested from a browser it is done using the GET method, so the POST array will be empty. Notice here that we are using the RESET button to clear all input.

```// look for no POST entries, or the RESET button
if (count(\$_POST) == 0 or isset(\$_POST['reset'])) {
// POST array is empty - set initial values
\$dec_input   = null;
\$dec_output  = null;
\$base2value  = null;
\$base8value  = null;
\$base16value = null;
\$base36value = null;
} else {
// retrieve values from POST array
\$dec_input   = &\$_POST['dec_input'];
\$dec_output  = null;
\$base2value  = &\$_POST['base2value'];
\$base8value  = &\$_POST['base8value'];
\$base16value = &\$_POST['base16value'];
\$base36value = &\$_POST['base36value'];
} // if
```

The `&` character is used in front of `\$_POST` to pass the value by reference instead of making a copy of that value. This also prevents the generation of a warning message if the value does not actually exist is the POST array.

This next section of code will look for a submit button to convert from decimal to one of the other formats. Notice that we are not using any of PHP's standard functions to perform this conversion, we are using a home-made routine which is described here.

```if (isset(\$_POST['dec-2-bin'])) {
\$base2value = dec2string(\$dec_input, 2);
} // if
if (isset(\$_POST['dec-2-oct'])) {
\$base8value = dec2string(\$dec_input, 8);
} // if
if (isset(\$_POST['dec-2-hex'])) {
\$base16value = dec2string(\$dec_input, 16);
} // if
if (isset(\$_POST['dec-2-b36'])) {
\$base36value = dec2string(\$dec_input, 36);
} // if
```

This next section of code will look for a submit button to convert into decimal from one of the other formats. Notice that we are not using any of PHP's standard functions to perform this conversion, we are using a home-made routine which is described here.

```if (isset(\$_POST['bin-2-dec'])) {
\$dec_output = string2dec(\$base2value, 2);
if (\$error) {
\$error['base2value'] = \$error;
} // if
} // if
if (isset(\$_POST['oct-2-dec'])) {
\$dec_output = string2dec(\$base8value, 8);
if (\$error) {
\$error['base8value'] = \$error;
} // if
} // if
if (isset(\$_POST['hex-2-dec'])) {
\$dec_output = string2dec(\$base16value, 16);
if (\$error) {
\$error['base16value'] = \$error;
} // if
} // if
if (isset(\$_POST['b36-2-dec'])) {
\$dec_output = string2dec(\$base36value, 36);
if (\$error) {
\$error['base36value'] = \$error;
} // if
} // if
```

This next piece of code is a method of quickly incrementing or decrementing the decimal input.

```if (isset(\$_POST['plus1'])) {
\$dec_input = \$dec_input +1;
} // if
if (isset(\$_POST['minus1'])) {
\$dec_input = \$dec_input -1;
} // if
```

Now we come to actually constructing the HTML output. We start with the `form` tag which tells the browser to call itself using the `POST` method when one of the buttons is pressed.

```<form action="<?php echo \$_SERVER['PHP_SELF'] ?>" method="POST">
```

For each line on the screen we need to supply a label, a text box which contains the current value (which may be empty), and we must also look for the possibility of an error message to be displayed for this field. Note here that `<?=` is just a shorthand version of `<?php echo`.

```    <td>Decimal (input)</td>
<td><input type="text" name="dec_input" value="<?= \$dec_input ?>" />
<?php
if (array_key_exists('dec_input', \$error)) {
echo '<p class="error">' .\$error['dec_input'] .'</p>';
} // if
?>
</td>
```

I shall not bother with all the other input fields as the code is very similar. You can view the complete source here.

### Decimal to String conversion

This routine will convert a decimal number (base 10) into a number with a different base. First we assign the global area to hold any error message and initialise the output.

```function dec2string (\$decimal, \$base)
{
global \$error;
\$string = null;
```

The next step is to make sure that the base number is valid. Note that this value can be any number between 2 and 36.

```    \$base = (int)\$base;
if (\$base < 2 | \$base > 36 | \$base == 10) {
echo 'BASE must be in the range 2-9 or 11-36';
exit;
} // if;
```

Next we set up the list of possible output characters, then chop off any characters beyond the limit specified by `\$base`.

```    \$charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
\$charset = substr(\$charset, 0, \$base);
```

Here we are checking that the input value is acceptable - a positive integer between 1 and 16 digits long.

```    if (!ereg('(^[0-9]{1,16}\$)', trim(\$decimal))) {
\$error['dec_input'] = 'Value must be a positive integer';
return false;
} // if
\$decimal = (int)\$decimal;
```

Here we are starting what is known as a `do` loop.

```    do {
```

Step 1 inside the loop is to get the remainder after dividing `\$decimal` by `\$base`.

```       \$remainder = (\$decimal % \$base);
```

Step 2 is to extract the character that corresponds to this remainder and add it to the front of the output string.

```       \$char   = substr(\$charset, \$remainder, 1);
\$string = "\$char\$string";
```

Step 3 is to reduce the decimal value by the number we have just processed. This is done by subtracting `\$remainder` then dividing by `\$base`.

```       \$decimal   = (\$decimal - \$remainder) / \$base;
```

This terminates the `do` loop when the input value has been reduced to zero.

```    } while (\$decimal > 0);
```

The function ends by passing back the completed string value to the calling process.

```    return \$string;

} // dec2string
```

### String to Decimal conversion

This routine will convert a number in base X to a decimal number. First we assign the global area to hold any error message and initialise the output.

```function string2dec (\$string, \$base)
{
global \$error;
\$decimal = 0;
```

The next step is to make sure that the base number is valid. Note that this value can be any number between 2 and 36.

```    \$base = (int)\$base;
if (\$base < 2 | \$base > 36 | \$base == 10) {
echo 'BASE must be in the range 2-9 or 11-36';
exit;
} // if;
```

Next we set up the list of possible output characters, then chop off any characters beyond the limit specified by `\$base`.

```    \$charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
\$charset = substr(\$charset, 0, \$base);
```

Here we are just checking that the input string is not empty.

```    \$string = trim(\$string);
if (empty(\$string) {
\$error[] = 'Input string is empty';
return false;
} // if
```

Here we start a `do` loop to process every character in the input string.

```    do {
```

Next we extract the first character from the input string, then remove it from the string.

```       \$char   = substr(\$string, 0, 1);
\$string = substr(\$string, 1);
```

Here we obtain the position of `\$char` in `\$charset`.

```       \$pos = strpos(\$charset, \$char);
if (\$pos === false) {
\$error[] = "Illegal character (\$char) in INPUT string";
return false;
} // if
```

Here we increment the decimal value by the value of the character we have just extracted from the input string.

```       \$decimal = (\$decimal * \$base) + \$pos;
```

Finally we can terminate the `do` loop and return the decimal value to the calling process.

```    } while(\$string <> null);

return \$decimal;

} // string2dec
```

## Summary

This may be a simple PHP script, but as well as a training exercise it produces a function which you may find useful some day.

## Amendment history:

 7th April 2004 Switched to BCMATH functions in order to deal with numbers greater than a 32 bit integer. 