<?php
//*****************************************************************************
// Copyright 2003 by A J Marston <http://www.tonymarston.net>
// Distributed under the GNU General Public Licence
//*****************************************************************************
//
// Convert a number from base10 (decimal) to baseX where X is is the range 2-36.
//
// It will also convert a number from baseX back into base10.
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Binary-Octal-Decimal-Hexadecimal Converter</title>
  <meta http-equiv='Content-type' content='text/html; charset=UTF-8' >
  <style type="text/css">
  <!--
    P.error { margin-top: 0pt; color: red; font-weight: bold; }
    TR.grey { background: #eeeeee; }
  -->
  </style>
</head>
<body>
<div align="center">
<h1>Bin-Oct-Dec-Hex Converter</h1>
<?php
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    $url = parse_url($_SERVER['REQUEST_URI']);
    if ($url['path'] != $_SERVER['PHP_SELF']) {
        // somebody is screwing with the URL! Posasible XSS attack!
        header('Location: ' .$_SERVER['SCRIPT_NAME']);
        exit;
    } // if
} // if
// remove any leading or trailing spaces from all inputs
foreach ($_POST as $key => &$value) {
    $value = trim((string)$value);
} // foreach
// 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
// initialise array for validation errors
$error = array();
if (!empty($dec_input) AND !is_numeric($dec_input)) {
    $error['dec_input'] = 'This is not numeric - try again';
} // if
if (empty($error)) {
    if (!empty($_POST['dec-2-bin'])) {
        $base2value = dec2string($dec_input, 2);
    } // if
    if (!empty($_POST['dec-2-oct'])) {
        $base8value = dec2string($dec_input, 8);
    } // if
    if (!empty($_POST['dec-2-hex'])) {
        $base16value = dec2string($dec_input, 16);
    } // if
    if (!empty($_POST['dec-2-b36'])) {
        $base36value = dec2string($dec_input, 36);
    } // if
    if (!empty($_POST['bin-2-dec'])) {
        $dec_output = string2dec($base2value, 2);
        if ($error) {
           $error['base2value'] = $error[0];
        } // if
    } // if
    if (!empty($_POST['oct-2-dec'])) {
        $dec_output = string2dec($base8value, 8);
        if ($error) {
           $error['base8value'] = $error[0];
        } // if
    } // if
    if (!empty($_POST['hex-2-dec'])) {
        $dec_output = string2dec($base16value, 16);
        if ($error) {
           $error['base16value'] = $error[0];
        } // if
    } // if
    if (!empty($_POST['b36-2-dec'])) {
        $dec_output = string2dec($base36value, 36);
        if ($error) {
           $error['base36value'] = $error[0];
        } // if
    } // if
    if (!empty($_POST['plus1'])) {
       $dec_input = bcadd($dec_input, 1);
    } // if
    if (!empty($_POST['minus1'])) {
       $dec_input = bcsub($dec_input, 1);
    } // if
} // if
?>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="POST">
<table border="0">
<colgroup align="right">
<colgroup align="left">
<colgroup align="left">
<colgroup align="left">
<tr>
    <td>Decimal (input)</td>
    <td><input type="text" name="dec_input" value="<?php echo $dec_input ?>" size="55" >
<?php
    if (array_key_exists('dec_input', $error)) {
        echo '<p class="error">' .$error['dec_input'] .'</p>';
    } // if
?>
    </td>
    <td><input type="submit" name="plus1" value="+1" > 
        <input type="submit" name="minus1" value="-1" ></td>
    <td></td>
</tr>
<tr>
    <td>Decimal (output)</td><td colspan="3"><?php echo $dec_output ?></td>
</tr>
<tr class="grey">
    <td>Binary (Base 2)</td>
    <td><input type="text" name="base2value" value="<?php echo $base2value ?>" size="40" >
<?php
    if (array_key_exists('base2value', $error)) {
        echo '<p class="error">' .$error['base2value'] .'</p>';
    } // if
?>
    </td>
    <td><input type="submit" name="dec-2-bin" value="DEC to BIN" ></td>
    <td><input type="submit" name="bin-2-dec" value="BIN to DEC" ></td>
</tr>
<tr class="grey">
    <td>Octal (Base 8)</td>
    <td><input type="text" name="base8value" value="<?php echo $base8value ?>" size="40" >
<?php
    if (array_key_exists('base8value', $error)) {
        echo '<p class="error">' .$error['base8value'] .'</p>';
    } // if
?>
    </td>
    <td><input type="submit" name="dec-2-oct" value="DEC to OCT" ></td>
    <td><input type="submit" name="oct-2-dec" value="OCT to DEC" ></td>
</tr>
<tr class="grey">
    <td>Hexadecimal (Base 16)</td>
    <td><input type="text" name="base16value" value="<?php echo $base16value ?>" size="40" >
<?php
    if (array_key_exists('base16value', $error)) {
        echo '<p class="error">' .$error['base16value'] .'</p>';
    } // if
?>
    </td>
    <td><input type="submit" name="dec-2-hex" value="DEC to HEX" ></td>
    <td><input type="submit" name="hex-2-dec" value="HEX to DEC" ></td>
</tr>
<tr class="grey">
    <td>Base 36</td>
    <td><input type="text" name="base36value" value="<?php echo $base36value ?>" size="40" >
<?php
    if (array_key_exists('base36value', $error)) {
        echo '<p class="error">' .$error['base36value'] .'</p>';
    } // if
?>
    </td>
    <td><input type="submit" name="dec-2-b36" value="DEC to B36" ></td>
    <td><input type="submit" name="b36-2-dec" value="B36 to DEC" ></td>
</tr>
</table>
<p><input type="submit" name="reset" value="reset" ></p>
</form>
</div>
</body>
</html>
<?php
function dec2string ($decimal, $base)
// convert a decimal number into a string using $base
{
    //DebugBreak();
   global $error;
   $string = null;
   $base = (int)$base;
   if ($base < 2 | $base > 36 | $base == 10) {
      echo 'BASE must be in the range 2-9 or 11-36';
      exit;
   } // if
   // maximum character string is 36 characters
   $charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
   // strip off excess characters (anything beyond $base)
   $charset = substr($charset, 0, $base);
   if (!preg_match('/(^[0-9]{1,50}$)/', trim($decimal))) {
      $error['dec_input'] = 'Value must be a positive integer with < 50 digits';
      return false;
   } // if
   do {
      // get remainder after dividing by BASE
      $remainder = bcmod($decimal, $base);
      $char      = substr($charset, $remainder, 1);   // get CHAR from array
      $string    = "$char$string";                    // prepend to output
      //$decimal   = ($decimal - $remainder) / $base;
      $decimal   = bcdiv(bcsub($decimal, $remainder), $base);
   } while ($decimal > 0);
   return $string;
} // dec2string
// ****************************************************************************
function string2dec ($string, $base)
// convert a string into a decimal number using $base
{
   global $error;
   $decimal = 0;
   $base = (int)$base;
   if ($base < 2 | $base > 36 | $base == 10) {
      echo 'BASE must be in the range 2-9 or 11-36';
      exit;
   } // if
   // maximum character string is 36 characters
   $charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
   // strip off excess characters (anything beyond $base)
   $charset = substr($charset, 0, $base);
   $string = trim($string);
   if (empty($string)) {
      $error[] = 'Input string is empty';
      return false;
   } // if
   do {
      $char   = substr($string, 0, 1);    // extract leading character
      $string = substr($string, 1);       // drop leading character
      $pos = strpos($charset, $char);     // get offset in $charset
      if ($pos === false) {
         $error[] = "Illegal character ($char) in INPUT string";
         return false;
      } // if
      //$decimal = ($decimal * $base) + $pos;
      $decimal = bcadd(bcmul($decimal, $base), $pos);
   } while($string <> null);
   return $decimal;
} // string2dec
?>