Geeks With Blogs
David Brown The Web Development Guy

Here's an extension method that packs a C# BitArray to a byte array:

public static byte[] ToByteArray(this BitArray bits) {
    int numBytes = bits.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 << (7 - bitIndex));

        bitIndex++;
        if (bitIndex == 8) {
            bitIndex = 0;
            byteIndex++;
        }
    }

    return bytes;
}

Special thanks to the good people at StackOverflow! Enjoy!

Posted on Sunday, April 5, 2009 3:23 PM | Back to top


Comments on this post: Convert a BitArray to byte[] in C#

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
You should be VERY careful using an extension method like that in production code.

Just on a cursory glance I can see that it could throw a dividebyzero exception and an indexofbounds exception. You would at the least want to ensure that any consumer code was aware of this potential.
Left by Steve Hoff on May 15, 2009 2:16 PM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
A common approach to do the conversion is:

byte[] bytes = new byte[bits.Length];
array.CopyTo(bits, 0);
Left by mcm on Aug 08, 2009 7:35 PM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
Sorry should be:

byte[] bytes = new byte[bits.Length];
bits.CopyTo(bytes, 0);
Left by mcm on Aug 08, 2009 7:37 PM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
Actually, that didn't work in my case. It came up in the discussion on StackOverflow. The CopyTo method produced the wrong result for some reason. To use it, you have to first reverse the original array before passing it to the constructor of BitArray. After your call to CopyTo, you then have to reverse the byte array. It's a bit of a hassle, but this extension method does it correctly from the start.
Left by David Brown on Aug 08, 2009 9:46 PM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
Absolute genius! I've been trying to find a solution to this problem for a few weeks now, daft how the function that originally should do this doesnt account for odd bits. Thanks for the heads up :)
Left by AmzBee on Aug 12, 2010 5:28 PM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
Tanxxx a lot Gravatar for your answer :)
Left by Elham on Sep 21, 2010 12:07 AM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
That do not work.
James Manning's version : http://blog.sublogic.com/2005/11/26/how-do-i-convert-a-bitarray-into-a-byte-array/

Solution:
byte[] byteArray = new byte[(int)Math.Ceiling((double)bitArray.Length / 8)];
bitArray.CopyTo(byteArray, 0);
Left by PlasmaSoft on Aug 12, 2011 11:19 AM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
Bug

...
bytes[byteIndex] |= (byte)(1 << (0 + bitIndex));
...
Left by Buratino on Nov 25, 2011 12:17 PM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
byte[] byteArray = new byte[(int)Math.Ceiling((double)bitArray.Length / 8)];
bitArray.CopyTo(byteArray, 0);

Great this is Correct
Left by Santhakumar D on Mar 11, 2012 6:33 AM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
bytes[byteIndex] |= (byte)(1 << (7 - bitIndex));

why to use the above code, could u pls explain me??
Left by priya on May 29, 2012 4:04 AM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
ToByteArray is working, thanks!
Left by cranioDev on Jun 27, 2013 11:14 PM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
var bytes = new byte[(bits.Length - 1) / 8 + 1];
bits.CopyTo(bytes, 0);
Left by ViTAR on Oct 03, 2013 8:10 AM

# re: Convert a BitArray to byte[] in C#
Requesting Gravatar...
The main issue with serializing bit-arrays is that the number of bits is not always divisible by 8, so one of the resulting bytes will only be partially set from the bit-array, meaning that when you try to restore the original bit-array, you could get up to 7 extra bits, with no way of knowing.

The only (generic) solution to this problem that I know, is to prefix the serialization with a pre-set number of bytes that contain the length of the bit-array.

/// <summary>
/// serialize a bitarray.
/// </summary>
/// <param name="bits"></param>
/// <returns></returns>
public static IEnumerable<byte> ToBytes(this BitArray bits)
{
// calculate the number of bytes
int numBytes = bits.Count / 8;

// add an extra byte if the bit-count is not divisible by 8
if (bits.Count % 8 != 0) numBytes++;

// reserve the correct number of bytes
byte[] bytes = new byte[numBytes];

// get the 4 bytes that make up the 32 bit integer of the bitcount
var prefix = BitConverter.GetBytes(bits.Count);

// copy the bit-array into the byte array
bits.CopyTo(bytes, 0);

// read off the prefix
foreach (var b in prefix)
yield return b;

// read off the body
foreach (var b in bytes)
yield return b;

}

Then when restoring the array:

/// <summary>
/// restore a BitArray from the enumeration of bytes
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static BitArray ToBitArray(this IEnumerable<byte> bytes)
{
// take the first 4 bytes and restore a 32 bit integer indicating the bit-length
int numBits = BitConverter.ToInt32(bytes.Take(4).ToArray(), 0);

// skipping the 4 leader bytes, restore the bitarray
var ba = new BitArray(bytes.Skip(4).ToArray());

// set the length exactly
ba.Length = numBits;

// return the bit-array;
return ba;
}
Left by Simon Bridge on Feb 18, 2016 7:19 PM

Your comment:
 (will show your gravatar)


Copyright © David Brown | Powered by: GeeksWithBlogs.net