Вопрос:

Конвертировать из BitArray в Byte

c# .net binary bitarray bcl

69586 просмотра

10 ответа

42443 Репутация автора

У меня есть 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);
Автор: Graviton Источник Размещён: 18.02.2009 07:13

Ответы (10)


47 плюса

1091787 Репутация автора

Решение

Это должно работать:

byte ConvertToByte(BitArray bits)
{
    if (bits.Count != 8)
    {
        throw new ArgumentException("bits");
    }
    byte[] bytes = new byte[1];
    bits.CopyTo(bytes, 0);
    return bytes[0];
}
Автор: Jon Skeet Размещён: 18.02.2009 07:17

4 плюса

2320 Репутация автора

Это должно сделать свое дело. Однако предыдущий ответ, скорее всего, лучший вариант.

    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;
    }

В приведенном вами примере полученный байт будет 0x80. Другими словами, первое значение в ядре BitArray соответствует первому биту в возвращаемом байте.

Автор: Caleb Vear Размещён: 18.02.2009 07:28

5 плюса

7597 Репутация автора

Решение для бедного человека:

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;
}
Автор: tehvan Размещён: 18.02.2009 07:45

33 плюса

7165 Репутация автора

Немного запоздалый пост, но это работает для меня:

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

Работает с:

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

,

Автор: Tedd Hansen Размещён: 06.01.2011 08:04

2 плюса

21 Репутация автора

Это должно быть окончательным. Работает с любой длиной массива.

private List<byte> BoolList2ByteList(List<bool> values)
    {

        List<byte> ret = new List<byte>();
        int count = 0;
        byte currentByte = 0;

        foreach (bool b in values) 
        {

            if (b) currentByte |= (byte)(1 << count);
            count++;
            if (count == 7) { ret.Add(currentByte); currentByte = 0; count = 0; };              

        }

        if (count < 7) ret.Add(currentByte);

        return ret;

    }
Автор: Dmitry Kakhovsky Размещён: 30.07.2011 09:28

0 плюса

184 Репутация автора

byte GetByte(BitArray input)
{
  int len = input.Length;
  if (len > 8)
    len = 8;
  int output = 0;
  for (int i = 0; i < len; i++)
    if (input.Get(i))
      output += (1 << (len - 1 - i)); //this part depends on your system (Big/Little)
      //output += (1 << i); //depends on system
  return (byte)output;
}

Ура!

Автор: NothinRandom Размещён: 25.04.2013 10:22

0 плюса

492 Репутация автора

Преобразователь байтового байта с прямым порядком байтов: первый бит (индексируемый с помощью «0») в BitArray, предположительно представляющий младший значащий бит (самый правый бит в бит-октете), который интерпретируется как «ноль» или «один» как двоичный.

 public static class BitArrayExtender {

    public static byte[] ToByteArray( this BitArray bits ) {

        const int BYTE = 8;
        int length = ( bits.Count / BYTE ) + ( (bits.Count % BYTE == 0) ? 0 : 1 );
        var bytes  = new byte[ length ];

        for ( int i = 0; i < bits.Length; i++ ) {

           int bitIndex  = i % BYTE;
           int byteIndex = i / BYTE;

           int mask = (bits[ i ] ? 1 : 0) << bitIndex;
           bytes[ byteIndex ] |= (byte)mask;

        }//for

        return bytes;

    }//ToByteArray

 }//class
Автор: underscore Размещён: 25.10.2014 07:15

1 плюс

2189 Репутация автора

В дополнение к ответу @JonSkeet вы можете использовать общий метод в качестве удара:

public static byte ToByte(this BitArray bits)
        {
            if (bits.Count != 8)
            {
                throw new ArgumentException("bits");
            }
            byte[] bytes = new byte[1];
            bits.CopyTo(bytes, 0);
            return bytes[0];
        }

И используйте как:

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

foo.ToByte();
Автор: combo_ci Размещён: 05.07.2017 08:57

1 плюс

581 Репутация автора

К сожалению, класс 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;
    }
}

Метод декодирует BitArray в байтовый массив с использованием логики LSB (менее значимый байт). Это та же логика, что и класс BitArray. Вызов метода с параметром MSB, установленным в значение true, приведет к получению декодированной байтовой последовательности MSB. В этом случае помните, что вам, возможно, также понадобится отменить окончательную коллекцию выходных байтов.

Автор: LoxLox Размещён: 01.12.2017 11:22

0 плюса

1 Репутация автора

Образец из моих кодов:

Public Shared Function BytesXor(a1 As Byte(), a2 As Byte()) As Byte()
    Dim ba1 As BitArray = New BitArray(a1)
    Dim ba2 As BitArray = New BitArray(a2)
    Dim intLength As Integer = System.Math.Min(a1.Length, a2.Length)
    Dim RetrunValue(intLength - 1) As Byte
    If ba1.Length > ba2.Length Then ba1.Length = ba2.Length
    If ba2.Length > ba1.Length Then ba2.Length = ba1.Length
    Dim ba3 As BitArray = ba1.Xor(ba2)
    Dim p As Integer = 0
    For i As Integer = 0 To intLength - 1
        Dim v As Integer = 0
        For j As Integer = 0 To 7
            If ba3.Get(p) Then
                'BitArray(Byte()) sorts bits from lower to higher
                '"BitArray to Byte" must be put by reverse order
                v += 1 << j
            End If
            p += 1
        Next
        RetrunValue(i) = CByte(v)
    Next
    Return RetrunValue
End Function
Автор: user11190429 Размещён: 12.03.2019 10:18
32x32