<?php
function big_base_convert ($numstring, $frombase, $tobase)
{
	$chars = "0123456789abcdefghijklmnopqrstuvwxyz";
	$nlen = strlen($chars);
	$tostring = substr($chars, 0, $tobase);
	
	// Validate
	if ($frombase < 2 || $frombase > $nlen) {
		throw new Exception("Invalid source base: " . $frombase . ". Must be in the range [2, " . $nlen . "]");
	}
	
	if ($tobase < 2 || $tobase > $nlen) {
		throw new Exception("Invalid destination base: " . $tobase . ". Must be in the range [2, " . $nlen . "]");
	}
	
	$length = strlen($numstring);
	$result = '';
	$number = array();
	
	for ($i = 0; $i < $length; $i++) {
		$number[$i] = strpos($chars, $numstring{$i});
		
		if ($number[$i] === FALSE)
			throw new Exception("Invalid notation: " . $number[$i]);

		if ($number[$i] >= $frombase)
			throw new Exception("Number value '" . $number[$i] . "' too big for base" . $frombase . " notation!");
	}
	
	do {
		 $divide = 0;
		 $newlen = 0;
		 for ($i = 0; $i < $length; $i++) {
			  $divide = $divide * $frombase + $number[$i];
			  if ($divide >= $tobase) {
					$number[$newlen++] = (int)($divide / $tobase);
					$divide = $divide % $tobase;
			  } elseif ($newlen > 0) {
					$number[$newlen++] = 0;
			  }
		 }
		
		 $length = $newlen;
		 $result = $tostring{$divide} . $result;
	} while ($newlen != 0);
	
	return $result;
}

$title = 'Base Convert';
$header = 'Base Convert';

$number = "";
$frombase = "";
$tobase = "";

if (isset($_POST['convert'])) {
	try {
		$number = $_POST['number'];
		$frombase = (int)$_POST['frombase'];
		$tobase = (int)$_POST['tobase'];
		
		$result = big_base_convert($number, $frombase, $tobase);
		
		$title = $number . '(' . $frombase . ') = ' . $result . '(' . $tobase . ')';
		$header = $number . '<sub>(' . $frombase . ')</sub> = ' . $result . '<sub>(' . $tobase . ')</sub>';
	} catch (Exception $e) {
		$error = $e->getMessage();
	}
}

require_once(dirname(__FILE__) . '/header.php');

// Verification
/*$binary="11010101001111010001110101000100011110010110110001111000010001010001111001100011010110110010010011010001011010000001001011111110001010101101101011010101010000100011101110010110010100111110001010010111010110011001111111100011001011011001110001111110000101011010010";
echo '<pre><code>';
print("<strong>6A9E8EA23CB63C228F31AD9268B4097F156D6AA11DCB29F14BACCFF196CE3F0AD2</strong>\n");
print(strtoupper(base_convert($binary, 2, 16))) . "\n";
print(strtoupper(big_base_convert($binary, 2, 16))) ."\n";
echo '</code></pre>';*/

// Stress test
/*$chars = "0123456789abcdefghijklmnopqrstuvwxyz";
$clen = strlen($chars);
for ($i = 0; $i < 10; $i++) {
	$frombase = rand(2, $clen);
	$tobase = rand(2, $clen);
	
	$rchars = substr($chars, 0, $frombase);
	$rclen = strlen($rchars);
	$rnum = "";
	for ($j = 0; $j < 100; $j++) {
		$v = rand(0, $rclen-1);
		$rnum .= $rchars{$v};
	}
	
	$n1 = big_base_convert($rnum, $frombase, $tobase);
	$n2 = big_base_convert($n1, $tobase, $frombase);
	if ($n2 != $rnum) {
		echo "FAILED ON $rnum()->$n2<br/>";
	}
}*/
?>
<h1><?php echo $header; ?></h1>
<?php
if (isset($error)) {
	?>
	<p class="error"><?php echo htmlspecialchars($error); ?></p>
	<?php
}
?>
<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>"<?php if (!isset($error)) echo ' class="success"'; ?>>
	<fieldset>
		<input type="submit" class="submit" name="convert" value="Convert" />
		<input type="text" name="number" id="number" value="<?php echo htmlspecialchars($number); ?>" />
		<sub>(<input type="text" name="frombase" id="frombase" class="small" maxlength="2" value="<?php echo htmlspecialchars($frombase); ?>" />)</sub> 
		to base<sub>(<input type="text" name="tobase" id="tobase" class="small" maxlength="2" value="<?php echo htmlspecialchars($tobase); ?>" />)</sub>
	</fieldset>
</form>
<?php
require_once(dirname(__FILE__) . '/footer.php');







