Converter de BitArray para Byte
-
05-09-2019 - |
Pergunta
Eu tenho um BitArray
com o comprimento de 8, e eu preciso de uma função para convertê-lo em um byte
. Como fazê-lo?
Especificamente, eu preciso de uma função correta de 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);
Solução
Isso deve funcionar:
byte ConvertToByte(BitArray bits)
{
if (bits.Count != 8)
{
throw new ArgumentException("bits");
}
byte[] bytes = new byte[1];
bits.CopyTo(bytes, 0);
return bytes[0];
}
Outras dicas
Um pouco pós tarde, mas isso funciona para mim:
public static byte[] BitArrayToByteArray(BitArray bits)
{
byte[] ret = new byte[(bits.Length - 1) / 8 + 1];
bits.CopyTo(ret, 0);
return ret;
}
Funciona com:
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
.
solução de um homem pobre: ??
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;
}
Isso deve fazer o truque. No entanto, a resposta anterior é bastante provável que a melhor opção.
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;
}
No exemplo que você postou o byte resultante será 0x80. Em outras palavras, o primeiro valor na coresponds BitArray para o primeiro bit no byte retornado.
Isso de deve ser o final. Funciona com qualquer comprimento de matriz.
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;
}
Além de @JonSkeet Resposta Você pode usar método genérico como o sopro:
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];
}
E o uso como:
BitArray foo = new BitArray(new bool[]
{
false, false, false, false,false, false, false, true
});
foo.ToByte();
Infelizmente, a classe BitArray é parcialmente implementado em classes .NET Núcleo (UWP). Por exemplo classe BitArray é incapaz de ligar para o CopyTo () e Contagem () métodos. Eu escrevi esta extensão para preencher a lacuna:
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;
}
O método descodifica o BitArray para uma matriz de bytes usando lógica LSB (byte menos significativo). Esta é a mesma lógica usada pela classe BitArray. Chamar o método com o conjunto de parâmetros MSB na verdade irá produzir um MSB decodificado seqüência de byte. Neste caso, lembre-se que você talvez também precisa reverter a colheita final byte de saída.
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;
}
Felicidades!
Little endian conversor de matriz de bytes: Primeiro bit (indexado com "0") no BitArray assumido que representa o bit menos significativo (o bit mais à direita no bit-octeto) que interpretada como ou "uma" "zero" como binário.
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
Uma amostra dos meus códigos:
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