Click here to Skip to main content
15,897,226 members
Articles / Programming Languages / C#

Hexadecimal, Binary, and Decimal conversions

Rate me:
Please Sign up or sign in to vote.
4.65/5 (24 votes)
22 Apr 20052 min read 230.9K   6.9K   83  
This project contains a class aimed to all possible combinations for hexadecimal, binary, and decimal conversions.
using System;
using System.Collections;
using System.Text;

namespace Bin
{
	/// -----------------------------------------------------------------------------
	/// Project	 : Bin
	/// Class	 : Bits
	/// 
	/// Use of this software is privilege of CodeProject members. Feel free to modify
	/// and report any bugs to Codeproject.com.
	/// 
	/// -----------------------------------------------------------------------------
	/// <summary>
	/// This class handles the bit manipulations.
	/// </summary>
	/// <remarks>
	/// This creates an array of booleans to store the binary representation of this class.
	/// </remarks>
	/// <history>
	/// 	[Rudy Guzman]	4/10/2005	Created
	/// </history>
	/// -----------------------------------------------------------------------------
	public class Bits
	{
		bool [] _bitArray;

		public int Count
		{
			get
			{ 
				if (_bitArray == null)
					return 0;
				else
					return _bitArray.Length;
			}
		}

		//----------------------------------------------------------------------------------------------------------------------------------------
		//			CONSTRUCTOR METHODS
		//----------------------------------------------------------------------------------------------------------------------------------------
		private Bits()
		{
		}
		/// <summary>
		/// Initialize a new instance of this class from an array that is ordered in a human readable format.  
		/// For example, if the input is:0x0B, 0x23, 0x84
		/// 0x0B = 0000 1011
		/// 0x23 = 0010 0011
		/// 0x84 = 1000 0100
		/// Then the array of bits will contain 0000 1011 0010 0011 1000 0100
		/// Note that the MSbit is actually at position 0 in the array (outer left)
		/// </summary>
		/// <param name="byteArray"></param>
		public Bits(byte [] byteArray)
		{
			if (byteArray.Length > 0)
				createArray(byteArray);
			else
				throw new ApplicationException("Can't convert to bits a zero length array of bytes");
		}

		/// <summary>
		/// Initialize a new instance of this class from an unsigned integer number.  
		/// Since we may need only a few bits of the 32 bit integer number, the second 
		/// parameter helps by specifying the number of useful bits to construct this class.
		/// </summary>
		/// <param name="data">Number that will be converted to bit array.</param>
		/// <param name="numBits">Number of bits required to build an array of bits.</param>
		public Bits(uint data, int numBits)
		{
			if (numBits == 0)
				throw new ApplicationException("Can't initialize bits when number of bits is 0");
			_bitArray = new bool[numBits];

			int bitIndex = 0;
			uint mask = Convert.ToUInt32(Math.Pow(2, numBits-1)); 
			for (int maskIndex = numBits-1; maskIndex >= 0; maskIndex--)
			{
				if ((data & mask) > 0)
					_bitArray[bitIndex] = true;
				else
					_bitArray[bitIndex] = false;
				bitIndex++;
				mask >>=1;
			}
		}

		/// <summary>
		/// Initialize a new instance of this class from an integer number.  
		/// Since we may need only a few bits of the 32 bit integer number, the second 
		/// parameter helps by specifying the number of useful bits to construct this class.
		/// </summary>
		/// <param name="data">Number that will be converted to bit array.</param>
		/// <param name="numBits">Number of bits required to build an array of bits.</param>
		public Bits(int data, int numBits)
		{
			if (numBits == 0)
				throw new ApplicationException("Can't initialize bits when number of bits is 0");

			if (data < 0)
				data += Convert.ToInt32(System.Math.Pow(2, numBits));

			_bitArray = new bool[numBits];

			int bitIndex = 0;
			int mask = Convert.ToInt32(Math.Pow(2, numBits-1)); 
			for (int maskIndex = numBits-1; maskIndex >= 0; maskIndex--)
			{
				if ((data & mask) > 0)
					_bitArray[bitIndex] = true;
				else
					_bitArray[bitIndex] = false;
				bitIndex++;
				mask >>=1;
			}
		}

		/// <summary>
		/// Initialize a new instance of this class from an instance of "Hex" data.
		/// </summary>
		/// <param name="hexData">Hexadecimal data that will be used to create a bit array.</param>
		public Bits(Hex hexData)
		{
			createArray(hexData.ToBytes());
		}

		/// <summary>
		/// Initialize a new instance of this class from a string that represents a binary number.
		/// </summary>
		/// <param name="data">String that contains a valid binary value.</param>
		public Bits(string data)
		{
			if (ValidBitString(data))
			{
				_bitArray = new bool[data.Length];
				for (int i = 0; i < data.Length; i++)
				{
					if (data[i] == '1')
						_bitArray[i] = true;
					else
						_bitArray[i] = false;
				}
			}
			else 
				throw new ApplicationException("Invalid binary number: " + data);
		}

		/// <summary>
		/// Constructs this class by using another array of bits.
		/// </summary>
		/// <param name="boolBits"></param>
		public Bits(bool [] boolBits)
		{
			if (boolBits.Length > 0)
			{
				_bitArray = new bool[boolBits.Length];
				for (int i = 0; i < _bitArray.Length; i++)
					_bitArray[i] = boolBits[i];
			}
			else
				throw new ApplicationException("Can't initialize Bits because the input arry of boolBits can't be zero length");
		}

		//----------------------------------------------------------------------------------------------------------------------------------------
		//			CONVERSION METHODS
		//----------------------------------------------------------------------------------------------------------------------------------------

		/// <summary>
		/// Convert to unsigned integer.
		/// </summary>
		/// <returns>Unsigned integer that represents the binary value of this instance.</returns>
		public uint ToUInt()
		{
			uint result = 0;
			if (_bitArray != null)
			{
				for (int i = 0; i < _bitArray.Length; i++)
				{
					//bit at position 0 is the MSBit so left shift bits from _bitArray
					result <<= 1;
					if (_bitArray[i] == true)
						result |= 1;
				}
			}
			return result;
		}

		/// <summary>
		/// Convert to SIGNED integer.
		/// </summary>
		/// <returns>
		/// SIGNED integer that represents the binary value of this instance.</returns>
		/// <remarks>
		/// This method uses two's complement method to convert convert from binary to signed integer number.
		/// </remarks>
		public int ToInt()
		{
			int result = Convert.ToInt32(this.ToUInt());
			int numBits = _bitArray.Length;
			int maxPositiveValue = Convert.ToInt32(System.Math.Pow(2, numBits-1)-1);
			if (result > maxPositiveValue)
				result -= Convert.ToInt32(System.Math.Pow(2, numBits));

			return result;
		}

		/// <summary>
		/// Convert to bytes
		/// </summary>
		/// <returns>Byte array that represents the binary value of this instance.</returns>
		/// <remarks>
		/// The byte array contains Least Significant Bit first.
		/// </remarks>
		public byte[] ToBytes()
		{
			byte [] bytes = null;
			if (_bitArray != null)
			{
				byte currByte = 0;
				int numBytes = (int)(_bitArray.Length-1) / 8 + 1;
				bytes = new byte[numBytes];
				int bitCnt = 0;
				int byteIndex = 0;
				for (int bitIndex = _bitArray.Length-1; bitIndex >= 0; bitIndex--)
				{
					currByte >>= 1;
					if (_bitArray[bitIndex] == true)
						currByte |= 0x80;
					//store byte every 8 bits
					bitCnt++;
					if ( bitCnt % 8 == 0)
					{
						bytes[byteIndex] = currByte;
						currByte = 0;
						byteIndex++;
					}
				}
				if (bitCnt % 8 != 0)
					currByte >>= (8 - (bitCnt % 8));  //right shift remaining bits
				//if last set of bits is less than 8 bits then it didn't get stored yet, so make sure to store it
				if (byteIndex < numBytes)
				{
					bytes[byteIndex] = currByte;
				}
				System.Array.Reverse(bytes);
			}
			return bytes;
		}

		/// <summary>
		/// Convert to Hex number.
		/// </summary>
		/// <returns>Hex number that represents the binary value of this instance.</returns>
		public Hex ToHex()
		{
			Hex hexData = new Hex(this.ToBytes());
			return hexData;
		}


		/// <summary>
		/// Converts the binary value of this instance to a string representation that
		/// follows a human readable convention (Least Significant Bit to farthest right).
		/// </summary>
		/// <returns>String that represents the binary value of this instance.</returns>
		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			if (_bitArray.Length > 0)
			{
				for (int i = 0; i < _bitArray.Length; i++)
				{
					if (_bitArray[i] == true)
						sb.Append('1');
					else
						sb.Append('0');
				}
			}
			return sb.ToString();
		}

		/// <summary>
		/// Convert to array of boolean.
		/// </summary>
		/// <returns>Array of boolean that represents the binary number of this instance.</returns>
		/// <remarks>The order of the bits in the array is: Least Significant Bit starts at 0 index position.</remarks>
		public bool[] ToBoolArray()
		{
			bool [] array = null;
			if (_bitArray.Length > 0)
			{
				array = new bool[_bitArray.Length];
				for (int i = 0; i < _bitArray.Length; i++)
					array[i] = _bitArray[i];
			}
			return array;
		}

		/// <summary>
		/// Extract bits from the specified location.  The position is calculated based on byte position,
		/// bit position within that byte position, and number of bits.
		/// Exact formula is as follows:
		///					From: (bytePosition + 1) * 8 - 1;
		///					  To: (bytePosition + 1) * 8 - (numBits + bitPosition);
		/// </summary>
		/// <param name="bytePosition">Byte position is indicated based on a human readable format.  
		/// For example, if this instance contains 32 bits such as: 0xAABBCCDD then byte byte 2 will be
		/// position of CC.</param>
		/// <param name="bitPosition">Indicates the bit position with respect to the byte position.
		/// For example, given 0xAABBCCDD and given byte 2 then byte 2 is 0xCC or 11001100 therefore,
		/// a bit position of 0 is the least significant bit which is a zero in this case.</param>
		/// <param name="numBits">The number of bits to get given a byte position, and bit position.
		/// For example, given 0xAABBCCDD, byte position 2, bit position 3 and number of bits=4 then
		/// the value returned will be 1001 (byte 2 = 11001100, then to get 4 bits from bit position
		/// 3 is: -1001--- the hyphens are the other bits that get removed.</param>
		/// <returns></returns>
		public Bits GetBits(int bytePosition, int bitPosition, int numBits)
		{
			int byteIndex = (bytePosition + 1) * 8 - 1;
			int from = byteIndex - (bitPosition + numBits) + 1;
			int to = byteIndex - bitPosition;
			if (from < 0 || to > (_bitArray.Length - 1) )
			{
				throw new ApplicationException("Unable to extract bits because the combination of byte position, bit position, and number of bits is not valid");
			}

			bool [] extractedBits = new bool[numBits];
			int index = 0;
			for (int i = from; i <= to; i++)
			{
				extractedBits[index] = _bitArray[i];
				index++;
			}
			
			return new Bits(extractedBits);	
		}



		#region UTILITY METHODS
		/// <summary>
		/// Verify that the string contains a valid sequence of bits.
		/// </summary>
		/// <param name="data">String representation of a binary number.</param>
		/// <returns>True if all digits are binary.</returns>
		public bool ValidBitString(string data)
		{
			bool validString = true;
			if (data != null)
			{
				for (int i = 0; i < data.Length; i++)
				{
					if (data[i] != '0' && data[i] != '1')
					{
						validString = false;
						break;
					}
				}
			}

			return validString;
		}

		/// <summary>
		/// Create a sequence of binary bits from an array of bytes.
		/// </summary>
		/// <param name="byteArray">Array of bytes that will be converted to bits.</param>
		/// <remarks>
		/// The it array is created in a human readable format.  For example,
		/// If we have an array such as AA BB CC DD, where AA is index 0 then the
		/// bit array will contain 10101010 10111011 11001100 11011101, where left most bit is the zero index.
		/// The representation of bits in this format makes it easy for string conversions.
		/// </remarks>
		private  void createArray(byte[] byteArray)
		{
			byte currByte, mask;
			_bitArray = new bool[byteArray.Length * 8];
		
			int bitIndex = 0;
			for (int i = 0; i < byteArray.Length; i++)
			{
				currByte = byteArray[i];
				//the mask initially is: 1000 0000 then we can test the 7th bit
				//then it becomes       : 0100 0000 so we can test the 6th bit
				mask = 0x80;
				for (int maskIndex = 7; maskIndex >= 0; maskIndex--)
				{
					if ((currByte & mask) > 0)
						_bitArray[bitIndex] = true;
					else
						_bitArray[bitIndex] = false;
					bitIndex++;
					mask >>=1;
				}
			}
		}
		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions