Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I convert bits to bytes?

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
like image 732
David Brown Avatar asked Apr 05 '09 19:04

David Brown


2 Answers

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.

like image 176
CAdaker Avatar answered Oct 13 '22 00:10

CAdaker


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);
like image 35
Lucas Avatar answered Oct 13 '22 00:10

Lucas