Convert from BitArray to Byte
This should work:
byte ConvertToByte(BitArray bits)
{
if (bits.Count != 8)
{
throw new ArgumentException("bits");
}
byte[] bytes = new byte[1];
bits.CopyTo(bytes, 0);
return bytes[0];
}
Converting BitArray to Byte
Because we count bits from the right and items from the left; for instance for
BitArray myBitArray = new BitArray(new byte[] { 10 });
We have for the byte
10
(counting from the right):
10 = 00001010 (binary)
^
second bit (which is 1)
when items of the corresponding array we count from the left:
{false, true, false, true, false, false, false, false}
^
corresponding second BitArray item (which is true)
That's why if we want to have an array of byte
back we have to Reverse
each byte
representation, e.g. Linq solution
using System.Collections;
using System.Linq;
...
BitArray myBitArray = ...
byte[] myByte = myBitArray
.OfType<bool>()
.Select((value, index) => new { // into chunks of size 8
value,
chunk = index / 8 })
.GroupBy(item => item.chunk, item => item.value)
.Select(chunk => chunk // Each byte representation
.Reverse() // should be reversed
.Aggregate(0, (s, bit) => (s << 1) | (bit ? 1 : 0)))
.Select(item => (byte) item)
.ToArray();
Byte[] to BitArray and back to Byte[]
This should do it
static byte[] ConvertToByte(BitArray bits) {
// Make sure we have enough space allocated even when number of bits is not a multiple of 8
var bytes = new byte[(bits.Length - 1) / 8 + 1];
bits.CopyTo(bytes, 0);
return bytes;
}
You can verify it using a simple driver program like below
// test to make sure it works
static void Main(string[] args) {
var bytes = new byte[] { 10, 12, 200, 255, 0 };
var bits = new BitArray(bytes);
var newBytes = ConvertToByte(bits);
if (bytes.SequenceEqual(newBytes))
Console.WriteLine("Successfully converted byte[] to bits and then back to byte[]");
else
Console.WriteLine("Conversion Problem");
}
I know that the OP is aware of the Array.CopyTo
solution (which is similar to what I have here), but I don't see why it's causing any Bit order issues. FYI, I am using .NET 4.5.2 to verify it. And hence I have provided the test case to confirm the results
BitArray to ByteArray not returning correct byte data
You could just use BitArray.CopyTo
:
byte[] bytes = new byte[4];
ba.CopyTo(bytes, 0);
Reference: https://stackoverflow.com/a/20247508
Bit array to Byte array
public class TestBitToByteEncoder {
public static void main(String[] args) {
int[] bits = new int[]{1, 0, 1, 0, 1, 1, 0, 1, 0, 1};
byte[] bytes = encodeToByteArray(bits);
}
private static byte[] encodeToByteArray(int[] bits) {
byte[] results = new byte[(bits.length + 7) / 8];
int byteValue = 0;
int index;
for (index = 0; index < bits.length; index++) {
byteValue = (byteValue << 1) | bits[index];
if (index %8 == 7) {
results[index / 8] = (byte) byteValue;
}
}
if (index % 8 != 0) {
results[index / 8] = (byte) byteValue << (8 - (index % 8));
}
return results;
}
}
Edit: If you are happy to store the bits in the opposite order within bytes:
private static byte[] encodeToByteArray(int[] bits) {
BitSet bitSet = new BitSet(bits.length);
for (int index = 0; index < bits.length; index++) {
bitSet.set(index, bits[index] > 0);
}
return bitSet.toByteArray();
}
Related Topics
How to Change the Color of Winform Datagridview Header
How to Programmatically List All Projects in a Solution
How to Put Text on Progressbar
How to Clear Browser Cache on Browser Back Button Click in MVC4
C# ASP.NET Write File to Client
How to Dispose of a Backgroundworker
Is Casting the Same Thing as Converting
Regex Word Boundary Expressions
How to Change Listbox Selection Background Color
Changing the View for a Viewmodel
Check If a Property Exists in a Class
Httpcontext.Current.Session Is Null in Ashx File
Webdriver How to Wait Until the Element Is Clickable in Webdriver C#
Using Webclient or Webrequest to Login to a Website and Access Data
The Entity or Complex Type ' ' Cannot Be Constructed in a Linq to Entities Query
Using a List as a Data Source for Datagridview
How to Split an Ienumerable<String> into Groups of Ienumerable<String>