Tutorial :How can I convert bits to bytes?



Question:

I have an array of 128 booleans that represent bits. How can I convert these 128 bit representations into 16 bytes?

Example:

I have an array that looks like this:

0110001100110000100010111011001011010011010001010001101101001100  1000010000000000001000111111111101000011111001111011111011111001  

(Converted to 1s and 0s to be more concise)

I need to convert those bits to the following byte array:

99 48 139 178 211 69 27 76 132 0 35 255 67 231 190 249  

EDIT: This doesn't seem to work:

public byte[] ToByteArray() {      int numBytes = Count / 8;        if (_bits.Count % 8 != 0) numBytes++;        byte[] bytes = new byte[numBytes];        int byteIndex = 0, bitIndex = 0;        for (int i = 0; i < _bits.Count; i++) {          if (_bits[i])              bytes[byteIndex] |= (byte)(1 << bitIndex);            bitIndex++;          if (bitIndex == 8) {              bitIndex = 0;              byteIndex++;          }      }        return bytes;  }  

It outputs:

198 12 209 77 203 162 216 50 33 0 196 255 194 231 125 159  


Solution:1

The code is treating the first bit as the low bit of the word, so you end up with each word reversed. As a quick-and-dirty fix, try this:

bytes[byteIndex] |= (byte)(1 << (7-bitIndex));  

That puts the first bit in the array at the highest position in the first byte, etc.


Solution:2

I don't know if there's an automatic way to do it, but you can do it with a simple algorithm.

Simple algorithm:

  1. Create an array of bytes that will be used as your output buffer, and initialize all bytes to 0. The size of this array should be based on the length of your input boolean array: ceil(bool_array_length / 8.0)

  2. Declare an index variable to be used as your current byte, and set it to 0. This holds the index in your output buffer.

  3. Iterate over each element in your input boolean array.
    3.1. Left bit shift the number 1 by the array index mod 8. Call this number your mask.
    3.2. Calculate your byte index as your current index into the array div 8.
    3.3. If you have a boolean true value the current index in your input boolean array, do a bitwise OR with your current byte and your mask.


Solution:3

bool[] bools = ...  BitArray a = new BitArray(bools);  byte[] bytes = new byte[a.Length / 8];  a.CopyTo(bytes, 0);  

EDIT: Actually this also returns:

198 12 209 77 203 162 216 50 33 0 196 255 194 231 125 159  

Wrong endianness? I'll leave answer anyway, for reference.


EDIT: You can use BitArray.CopyTo() by reversing the arrays like so:

bool[] bools = ...  Array.Reverse(bools); // NOTE: this modifies your original array  BitArray a = new BitArray(bools);  byte[] bytes = new byte[a.Length / 8];  a.CopyTo(bytes, 0);  Array.Reverse(bytes);  


Solution:4

Try this function (written as an extension method).

public byte[] ToByteArray(this bool[] bits)  {      var bytes = new byte[bits.Length / 8];      for (int i = 0, j = 0; j < bits.Length; i++, j += 8)      {          // Create byte from bits where LSB is read first.          for (int offset = 0; offset < 8; offset++)              bytes[i] |= (bits[j + offset] << offset);      }        return bytes;  }  

Note: It will fail if the number of bits (bools) is not a multiple of 8, but judging by your question this isn't the case. It would only take a very small modificaiton to permit bit arrays of any length.


Solution:5

private static byte[] GetBytes(string bitString)  {      byte[] result = Enumerable.Range(0, bitString.Length / 8).          Select(pos => Convert.ToByte(              bitString.Substring(pos * 8, 8),              2)          ).ToArray();        List<byte> mahByteArray = new List<byte>();      for (int i = result.Length - 1; i >= 0; i--)      {          mahByteArray.Add(result[i]);      }        return mahByteArray.ToArray();  }    private static String ToBitString(BitArray bits)  {      var sb = new StringBuilder();        for (int i = bits.Count - 1; i >= 0; i--)      {          char c = bits[i] ? '1' : '0';          sb.Append(c);      }        return sb.ToString();  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »