如何将布尔数组转换为一个字节,然后再将其转换回布尔数组

12
我想把最大长度为8的布尔数组打包到一个字节中,通过网络发送,然后再解包回布尔数组。我已经尝试了一些方法,但没能成功。 我正在使用Mono。
我创建了一个BitArray,然后尝试将其转换为字节。
public static byte[] BitArrayToByteArray(BitArray bits)
    {
      byte[] ret = new byte[Math.Max(1, bits.Length / 8)];
      bits.CopyTo(ret, 0);
      return ret;
    }

但我收到错误提示,只能使用int和long类型。尝试使用int代替byte,但仍然出现同样的问题。如果可能的话,我想避免使用BitArray,而是使用从bool数组到byte的简单转换。


2
你能具体说明你尝试了什么吗?给我们展示一些代码?你也能展示一下输入数据和期望的输出数据吗?实际的代码将起到决定性作用,并且可以避免被踩。 - Enigmativity
你能发布一下具体的错误信息吗? - Patrick Hofman
4个回答

26

下面是我如何实现它的方法。

bool[] 转换为 byte 的方法:

private static byte ConvertBoolArrayToByte(bool[] source)
{
    byte result = 0;
    // This assumes the array never contains more than 8 elements!
    int index = 8 - source.Length;

    // Loop through the array
    foreach (bool b in source)
    {
        // if the element is 'true' set the bit at that position
        if (b)
            result |= (byte)(1 << (7 - index));

        index++;
    }

    return result;
}

将一个字节转换为长度为8的布尔数组:

private static bool[] ConvertByteToBoolArray(byte b)
{
    // prepare the return result
    bool[] result = new bool[8];

    // check each bit in the byte. if 1 set to true, if 0 set to false
    for (int i = 0; i < 8; i++)
        result[i] = (b & (1 << i)) != 0;

    // reverse the array
    Array.Reverse(result);

    return result;
}

3

其他静态函数版本

/// <summary>
/// Convert Byte Array To Bool Array
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static bool[] ConvertByteArrayToBoolArray(byte[] bytes)
{
    System.Collections.BitArray b = new System.Collections.BitArray(bytes);
    bool[] bitValues = new bool[b.Count];
    b.CopyTo(bitValues, 0);
    Array.Reverse(bitValues);
    return bitValues;
}

/// <summary>
/// Packs a bit array into bytes, most significant bit first
/// </summary>
/// <param name="boolArr"></param>
/// <returns></returns>
public static byte[] ConvertBoolArrayToByteArray(bool[] boolArr)
{
    byte[] byteArr = new byte[(boolArr.Length + 7) / 8];
    for (int i = 0; i < byteArr.Length; i++)
    {
        byteArr[i] = ReadByte(boolArr, 8 * i);
    }
    return byteArr;
}

如果我在 .Net 6.0 中尝试这样做,我会得到一个 CS0103 The name 'ReadByte' does not exist in the current context。你有检查过 ReadByte 吗?虽然 C# 中有 ReadByte 实现,但它们需要某种类型的 Stream。 - user2986756

1

没有 Array.Reverse 版本:

public static void Byte2Flags(bool[] flags, byte range)
{
    if (flags == null || flags.Length < 8)
    {
        return;
    }

    for (int i = 0; i < 8; i++)
        flags[i] = (range & (1 << i)) > 0;
}

public static byte Flags2Byte(bool[] flags)
{
    byte range = 0;
    if (flags == null || flags.Length < 8)
    {
        range = 0;
    }

    for (int i = 0; i < 8; i++)
    {
        if (flags[i])
        {
            range |= (byte)(1 << i);
        }
    }

    return range;
}

并且如何进行测试:

    bool[] flags = new bool[8];
    byte b;

    for(int i = 0; i < 256; i++)
    {
        b = (byte)i;
        Byte2Flags(flags, b);
        byte back = Flags2Byte(flags);

        if(b != back)
        {
            //Not Match!
        }
    }

0
这里有一系列可以做到这件事的方法。
using System;
using System.Text;                  
public class Program
{
    public void Main(){     
      byte _num = 1;
        Console.WriteLine(ReadAllBits(WriteBools(new bool[] {true,true,false,false,false,false,false,true})));
    }
    
    public string ReadAllBits(byte _mask){
        string _data = "";
        for(int i = 0; i < 8; i++){
            if((_mask& (1<<i)) !=0){
                _data += "1";
            }else{
                _data+="0";
            }
        }
        return _data;
    }
    
    public bool[] GetBools(byte _mask){
        bool[] _values = new bool[8];
        for(int i = 0; i < 8; i++){
            if((_mask& (1<<i)) !=0){
                _values[i] = true;
            }else{
                _values[i] = false;
            }
        }
        return _values;
    }
    
    public byte WriteBools(bool[] _data){
        byte _byte = 0;
            for(int i = 0; i < 8; i++){
                if(_data[i]){
                    _byte = System.Convert.ToByte(( _byte | (1<<i)));
                }
            }
        return _byte;
    }
}

你可以在这里找到完整的代码片段 https://gist.github.com/namusanga/abecca458a3a15ca9bfa6fcdd7953e31


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接