views:

128

answers:

4

I have a string representing bits, such as:

"0000101000010000"

I want to convert it to get an array of bytes such as:

{0x0A, 0x10}

The number of bytes is variable but there will always be padding to form 8 bits per byte (so 1010 becomes 000010101).

A: 

This should get you to your answer: http://stackoverflow.com/questions/719502/how-can-i-convert-bits-to-bytes

You could just convert your string into an array like that article has, and from there use the same logic to perform the conversion.

Andrew Anderson
+3  A: 

Use the builtin Convert.ToByte() and read in chunks of 8 chars without reinventing the thing..

Unless this is something that should teach you about bitwise operations.

Update:


Stealing from Adam (and overusing LINQ, probably. This might be too concise and a normal loop might be better, depending on your own (and your coworker's!) preferences):

public static byte[] GetBytes(string bitString) {
    return Enumerable.Range(0, bitString.Length/8).
        Select(pos => Convert.ToByte(
            bitString.Substring(pos*8, 8),
            2)
        ).ToArray();
}
Benjamin Podszun
While I'd advocate that, the only issue is that a very long bit string (though I'd have to wonder why you have that in the first place) will result in a very large number of substrings.
Adam Robinson
This is likely what i will go with. After i formulated the question, i realized that going through the string in chunks of 8 characters would be easiest. The string will likely represent 10-12 bytes so the cost in execution time is not great.Once i confirm that it all works ill give an update
Lily
+1  A: 
public static byte[] GetBytes(string bitString)
{
    byte[] output = new byte[bitString.Length / 8];

    for (int i = 0; i < output.Length; i++)
    {
        for (int b = 0; b <= 7; b++)
        {
            output[i] |= (byte)((bitString[i * 8 + b] == '1' ? 1 : 0) << (7 - b));
        }
    }

    return output;
}
Adam Robinson
bitString.Length / 8 won't always round up. If you pass in "010" as the string, the array returned will have a length of 0.
Tim Coker
@Tim: You're absolutely right, in fact it will always round *down* (integer division truncates the remainder; it doesn't round). However, the OP explicitly said that the strings would contain a full eight bits per byte.
Adam Robinson
She isn't explicit on where the padding is done, actually. I assumed the function would accept smaller strings. She may mean that the function will receive pre-padded strings. Does she want the function to silently ignore longer strings that don't make the full 8 bits? Silently disregarding data never sits right with me. If its guaranteed to be divisible by 8, it wouldn't hurt to make that clear with an assertion or exception or something. This is all kind of irrelevant navel gazing at this point, really, though. :)
Tim Coker
@Tim: Acknowledging the navel gazing that's going on here, "...will always be padding to form 8 bits per byte (so 1010 becomes 000010101)." seems to say pretty clearly that there...will always be 8 bits per byte. ;)
Adam Robinson
The above statement from Adam is correct. I wont go into a entire explanation of the program but it is safe to assume that each byte will have a full 8 bit.
Lily
A: 

Get the characers in groups of eight, and parse to a byte:

string bits = "0000101000010000";

byte[] data =
  Regex.Matches(bits, ".{8}").Cast<Match>()
  .Select(m => Convert.ToByte(m.Groups[0].Value, 2))
  .ToArray();
Guffa
Ouch. A regex just to read every N (=8) characters? Works, but seems abusive to me..
Benjamin Podszun
@Benjamin: Yes, it'a bit of overhead, but it's a simple way to chop up a string and it works well enough for most purposes. Having bits in a string doesn't seem like a scenario where the highest performance is required anyway...
Guffa
The scenario is an odd patch to import an old file format, saved with a prototype of the program made years ago. The data must be reformatted into the new programs data structure. The files aren't that big and this feature will not be used too often, so performance is not an issue.
Lily