How can I convert bits to bytes?

前端 未结 5 1066
無奈伤痛
無奈伤痛 2020-12-03 11:55

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

相关标签:
5条回答
  • 2020-12-03 12:34

    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.

    0 讨论(0)
  • 2020-12-03 12:37
    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();
    }
    
    0 讨论(0)
  • 2020-12-03 12:40

    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.

    0 讨论(0)
  • 2020-12-03 12:40
    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);
    
    0 讨论(0)
  • 2020-12-03 12:53

    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.

    0 讨论(0)
提交回复
热议问题