0
votes

I'm working on some code that takes a hexadecimal string input and produces the binary value of that input. Once I have the value of the hexadecimal string in binary, I need to access individual bits of that byte.

I can't say exactly what I'm working on, but I can say this: The hex characters represent byte value of a given selection of registers on some hardware - which gives us the hex string as it's output after it has finished crunching some numbers.

As a made up example, the output value "A2" (10100010) will mean that the registers (again made up) will have the following values:

RegA  RegB  RegC  RegD
 101     0   001     0

I need to access N number of bits within the byte values that are returned. Except I've hit a bump in the road.

So far, I've tried the following:

string inputString = "F";
byte[] byteValues = new byte[inputString.Length * sizeof(char)];
System.Buffer.BlockCopy(inputString.ToCharArray(), 0, byteValues,
                        0, byteValues.Length);
return byteValues;

However, when given the input string "F", this code returns a byte array with 4 elements. The 1st element has the value 70 in it and the rest have 0. Which is the ASCII key for capital F - not what I want.

I have also tried:

int tempInt = Convert.ToInt32("F", 16);
byte[] value = BitConverter.GetBytes(tempInt);

When given the input string "F", this code returns a byte array with 4 elements. The 1st element has the value 15 in it and the rest have 0. This is more like it, but I now need to access individual bits within this 1st element of the byte array.

Is there a programmatic way to get individual bit information, other than providing a method that will take a hex character in, switch on it and return a 4 element byte[] with the correct bit values for that hex character?

This is what I mean:

public byte[] getByteValueForString (string inputString)
{
  /* is there a better way than this? */
  switch(inputString)
  {
     case "0":
       return new byte[] {0, 0, 0, 0};
     //....
     case "E":
       return new byte[] {1, 1, 1, 0};
     case "F":
       return new byte[] {1, 1, 1, 1};
  }
}

//or a similar method that switches on the output
//of Convert.ToInt32(string, 16) and returns the a
//byte[] in the same manner as getByteValueForString

public bool bar ()
{
  /* check the value for some representation
   * of a register */
  if (fooByteArray[2] == 0 & fooByteArray[3] == 0)
  {
    //some register, on the remote machine, is set to false
    return false;
  }
}

Any help with this would be greatly appreciated.

2
Why do you want 4 bytes (32 bits) to represent 4 bits? Why not just use a single byte, and access the bits via bit twiddling? - Jon Skeet
The only reason I'm using 4 bytes to represent 4 bits was because I couldn't figure out which object to use to represent individual bits. - Jamie Taylor
You could use a single byte, or use BitArray, or BitVector32, or write your own struct to hide it all away. - Jon Skeet

2 Answers

2
votes

I'd personally just use a single byte for this, rather than splitting 4 bits across 4 bytes. At that point you can just use:

byte b = Convert.ToByte(text, 16);

If you really want 4 bytes, you could use:

// Note: name changed to comply with .NET conventions
static byte[] GetByteValuesForString(string text)
{
    // TODO: Consider what you want to happen for invalid input.
    // You can easily write your own equivalent, ideally for a
    // single char
    byte value = Convert.ToByte(text, 16);
    return new byte[] {
        (byte) (value >> 3) & 1, 
        (byte) (value >> 2) & 1,
        (byte) (value >> 1) & 1,
        (byte) (value >> 0) & 1
    };
}
1
votes

The only reason I'm using 4 bytes to represent 4 bits was because I couldn't figure out which object to use to represent individual bits.

Take a look at System.Collection.BitArray class.

 byte[] byteArray = new byte[yourString.Length / 2];
 for(int i = 0; i < byteArray.Length; ++i)  
 { 
     int tempInt1 = Convert.ToInt32(yourString[i], 16); 
     int tempInt2 = Convert.ToInt32(yourString[i + 1], 16);
     byteArray[i] = (byte)(tempInt1 << 4 + tempInt2);
 }

BitArray bits = new BitArray(byteArray);
for (int i = 0; i = bits.Count; ++i)
{
   Console.WriteLine(bits[i]);
}