从BitArray转换为Byte

Gra*_*ton 31 .net c# binary bitarray base-class-library

我有一个BitArray长度为8,我需要一个函数将其转换为byte.怎么做?

具体来说,我需要一个正确的功能ConvertToByte:

BitArray bit = new BitArray(new bool[]
{
    false, false, false, false,
    false, false, false, true
});

//How to write ConvertToByte
byte myByte = ConvertToByte(bit);
var recoveredBit = new BitArray(new[] { myByte });
Assert.AreEqual(bit, recoveredBit);
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 49

这应该工作:

byte ConvertToByte(BitArray bits)
{
    if (bits.Count != 8)
    {
        throw new ArgumentException("bits");
    }
    byte[] bytes = new byte[1];
    bits.CopyTo(bytes, 0);
    return bytes[0];
}
Run Code Online (Sandbox Code Playgroud)

  • 记住:这会以相反的顺序计算位,例如,示例中的BitArray将转换为128,而不是1! (11认同)
  • @kornelijepetak:重要的是它以相反的顺序复制.如果在其他类型上使用BitConverter,则它们以little-endian格式存储. (4认同)
  • 绘制字节字节序和位字节序之间的区别非常重要.位字节序告诉您每个字节中位的排序以及第一位是最高位还是最低位.字节字节顺序告诉您字中字节的预期顺序.位字节顺序通常总是被描述为"LSB优先"或"MSB优先"而不是小端或大端... (2认同)
  • 颠倒顺序:`var reversed = new BitArray(bitArray.Cast<bool>().Reverse().ToArray());` (2认同)

Ted*_*sen 34

有点晚了,但这对我有用:

public static byte[] BitArrayToByteArray(BitArray bits)
{
    byte[] ret = new byte[(bits.Length - 1) / 8 + 1];
    bits.CopyTo(ret, 0);
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

适用于:

string text = "Test";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(text);
BitArray bits = new BitArray(bytes);
bytes[] bytesBack = BitArrayToByteArray(bits);
string textBack = System.Text.Encoding.ASCII.GetString(bytesBack);
// bytes == bytesBack
// text = textBack
Run Code Online (Sandbox Code Playgroud)

.

  • 您应该使用"(bits.Length - 1)/ 8 + 1"代替"bits.Length/8",否则如果BitArray的长度为7,则您的字节数组将为空." - 1"部分确保8的倍数不会返回加1.感谢http://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division/503201#503201 (14认同)
  • @TeddHansen 15 怎么样? (2认同)

Lox*_*Lox 6

不幸的是,BitArray 类在 .Net Core 类 (UWP) 中部分实现。例如,BitArray 类无法调用 CopyTo() 和 Count() 方法。我写了这个扩展来填补空白:

public static IEnumerable<byte> ToBytes(this BitArray bits, bool MSB = false)
{
    int bitCount = 7;
    int outByte = 0;

    foreach (bool bitValue in bits)
    {
        if (bitValue)
            outByte |= MSB ? 1 << bitCount : 1 << (7 - bitCount);
        if (bitCount == 0)
        {
            yield return (byte) outByte;
            bitCount = 8;
            outByte = 0;
        }
        bitCount--;
    }
    // Last partially decoded byte
    if (bitCount < 7)
        yield return (byte) outByte;
}
Run Code Online (Sandbox Code Playgroud)

该方法使用 LSB(低位字节)逻辑将 BitArray 解码为字节数组。这与 BitArray 类使用的逻辑相同。调用 MSB 参数设置为 true 的方法将生成 MSB 解码的字节序列。在这种情况下,请记住您可能还需要反转最终的输出字节集合。


Cal*_*ear 5

这应该可以解决问题。然而,之前的答案很可能是更好的选择。

    public byte ConvertToByte(BitArray bits)
    {
        if (bits.Count > 8)
            throw new ArgumentException("ConvertToByte can only work with a BitArray containing a maximum of 8 values");

        byte result = 0;

        for (byte i = 0; i < bits.Count; i++)
        {
            if (bits[i])
                result |= (byte)(1 << i);
        }

        return result;
    }
Run Code Online (Sandbox Code Playgroud)

在您发布的示例中,结果字节将为 0x80。换句话说,BitArray 中的第一个值对应于返回字节中的第一个位。


teh*_*van 5

一个穷人的解决方案:

protected byte ConvertToByte(BitArray bits)
{
    if (bits.Count != 8)
    {
        throw new ArgumentException("illegal number of bits");
    }

    byte b = 0;
    if (bits.Get(7)) b++;
    if (bits.Get(6)) b += 2;
    if (bits.Get(5)) b += 4;
    if (bits.Get(4)) b += 8;
    if (bits.Get(3)) b += 16;
    if (bits.Get(2)) b += 32;
    if (bits.Get(1)) b += 64;
    if (bits.Get(0)) b += 128;
    return b;
}
Run Code Online (Sandbox Code Playgroud)