Computer Science 101

with:  Erik Oosterwal

Search for specific programs or algorithms:
Custom Search





Numeric Base Conversion


The algorithm described in this article is a broad range conversion algorithm that will convert numbers from any base to any other base.  It requires the numbers to be in string variables.  For specialized algorithms to convert between decimal and hexadecimal values check out the Decimal to Hexadecimal and Hexadecimal to Decimal articles in Computer Science 101.

This algorithm is taken from a programming book I bought years ago when I was back in college called Practical BASIC Programs edited by Lon Poole and published by Osborne/McGraw-Hill, copyright 1980. Some of the contributors include Steven Cook, Martin McNiff, Robert Thomson, Dr. Richard E. Beckwith, and Dr. Samuel H. Westerman.

The basis behind the routine is fairly simple--you provide a string of characters starting at '0' and ending with whatever maximum size base you wish to work with (in this case we'll end with 'Z' and have the capability of base 36 numbers), convert the original number from whatever base is specified to base 10, then convert that base 10 number to the desire output base.

The pseudo-code provided below should be enough to get you started on implementing the algorithm into your language of choice.  To make the conversion to your computer language of choice easier, all variable names appear in bold text.  The 'int' command in the following code returns the whole part of the given number and drops the fractional part without rounding.  The 'mid' command is a string function that takes three parts; the first parameter is a string or string variable, the second parameter is an index pointer into the string, and the last parameter is the number of characters to return.



string function Base2Base(InputNumber as string, InputBase as integer, OutputBase as integer)
  Dim J, K, DecimalValue, X, MaxBase, InputNumberLength as integer
  Dim NumericBaseData, OutputValue as string
  NumericBaseData = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  MaxBase = Length(NumericBaseData)
  if (InputBase > MaxBase) OR (OutputBase > MaxBase) then
    Base2Base = "N/A"
    return
  end if
*/ Convert InputNumber to Base 10 /*
  InputNumberLength = Length(InputNumber)
  DecimalValue = 0
  for J = 1 to InputNumberLength
    for K = 1 to InputBase
      if mid(InputNumber, J, 1) == mid(NumericBaseData, K, 1) then
        DecimalValue = DecimalValue+int((K-1)*(InputBase^(InputNumberLength-J))+.5)
      end if
    next K
  next J
*/ Convert the Base 10 value (DecimalValue) to the desired output base /*
  OutputValue = ""
  while DecimalValue > 0
    X = int(((DecimalValue/OutputBase)-int(DecimalValue/OutputBase))*OutputBase+1.5)
    OutputValue = mid(NumericBaseData, X, 1)+OutputValue
    DecimalValue = int(DecimalValue/OutputBase)
  loop
  Base2Base = OutputValue
  return
end



There are a number of enhancements that can be made to this function to make it more suitable for specific applications.  For instance, if you are only converting between Binary, Octal, and Decimal, you can reduce the size of the NumericBaseData string to 0-9, or even use a different function that doesn't use strings at all. If the maximum base you're dealing with is Base 16 (Hexadecimal) reduce NumericBaseData to the digits 0-9 and the letters A-F.

By adding a space character " " to NumericBaseData, you can use this algorithm for encrypting text with capital letters and numbers.  You could make the encryption more secure by shuffling the order of the letters and numbers.  By increasing NumericBaseData to include lower case letters and punctuation, as well as digits and capital letters, you could make the encryption even more secure.  The senders and receivers of the messages would have to have identical copies of NumericBaseData then they only need to send the input and output base numbers with the encrypted messages in order to decipher them.


If you want to use this algorithm for encryption but you don't want it to look like an encrypted message you could add the following modifications:

Replace NumericBaseData with several string arrays.  Each array would include whole words that are commonly used in speech as well as words used specifically for the task at hand and as many uncommon words that are unrelated to the task at hand as you can.  There would be separate arrays for each part of speech, ie. a noun array, a verb array, a preposition array, an adjective array, an adverb array, etc.  Each array would have to have the same number of words.  In order to keep from decrypting the message incorrectly, there could be no duplication of words between arrays.  For instance, the word 'fast' can be used as a noun, verb, adjective, or adverb depending on the context of the sentence.  In cases like this, put the word in the array where it is used most often, or don't use it at all.  When encrypting the original message, each word would be replaced with a different word of the same part of speech.  A casual observer of the encrypted message would read normal language but not be able to decipher the message, or the message would appear to give false information about the subject matter.


While I have not yet implemented such code, bookmark this page and check back occasionally for updates on ways to encrypt text messages with other types of text messages.

Maurice Kherlakian has been kind enough to translate the the code listed above to PHP. Maurice's code follows and includes a test at the end to demonstrate the speed of the routine. In testing, Maurice was able to perform about 13,000 conversions per second, but it was not stated what hardware was being used for the speed test.



<?php

define('BASE_CONV',
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');

function base2Base($inputNumber, $inputBase, $outputBase) {
	$maxBase = strlen(BASE_CONV);
	
	if($inputBase > $maxBase || $outputBase > $maxBase) {
		return 'N/A';
	}
	
	/* Convert input number to base 10 */
	$inputNumberLength = strlen($inputNumber);
	$decimalValue = 0;
	
	for($j = 0; $j < $inputNumberLength; $j++) {
		for($k = 0; $k < $inputBase; $k++ ) {
			if(substr($inputNumber, $j, 1) == substr(BASE_CONV, $k, 1)) {
				$decimalValue = $decimalValue + (int)(($k)*bcpow($inputBase, $inputNumberLength - ($j+1)) + 0.5);
				break;
			}
		}
	}
	//for debugging. Comment out.
	echo 'in decimal value: ' . $decimalValue . '<br />';
	
	$outputValue = "";
	
	
	do {
		$x=(int)((($decimalValue/$outputBase) - (int)($decimalValue/$outputBase))*$outputBase + 1.5);
		$outputValue = substr(BASE_CONV, $x - 1, 1) . $outputValue;
		$decimalValue = (int)($decimalValue/$outputBase);
	} while($decimalValue > 0); 

	//for debugging. Comment out.	
	echo "out base " . $outputBase . " value: " . $outputValue . '<br />';
	return $outputValue;
}

//Testing.
$start = time();
echo time();

for($i=0; $i < 2048; $i++) {
	base2Base($i, 10, 62);	
}

$end = time() - $start;
echo time();

?>





Discuss computer algorithms and other computer science topics at the Computer Algorithms blog page.

All code and original algorithms are © Erik Oosterwal - 1987-2008
Computer Science 101

Dressing for Success