J'ai un BitArray
d'une longueur de 8 et j'ai besoin d'une fonction pour le convertir en un byte
. Comment faire?
Plus précisément, j'ai besoin d'une fonction correcte 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);
Cela devrait fonctionner:
byte ConvertToByte(BitArray bits)
{
if (bits.Count != 8)
{
throw new ArgumentException("bits");
}
byte[] bytes = new byte[1];
bits.CopyTo(bytes, 0);
return bytes[0];
}
Un peu tardif, mais ça marche pour moi:
public static byte[] BitArrayToByteArray(BitArray bits)
{
byte[] ret = new byte[(bits.Length - 1) / 8 + 1];
bits.CopyTo(ret, 0);
return ret;
}
Marche avec:
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
.
La solution d'un homme pauvre:
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;
}
Cela devrait faire l'affaire. Cependant, la réponse précédente est très probablement la meilleure option.
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;
}
Dans l'exemple que vous avez posté, l'octet résultant sera 0x80. En d'autres termes, la première valeur dans BitArray correspond au premier bit de l'octet renvoyé.
Cela devrait être l'ultime. Fonctionne avec n'importe quelle longueur de tableau.
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;
}
Malheureusement, la classe BitArray est partiellement implémentée dans la classe .Net Core (UWP). Par exemple, la classe BitArray ne peut pas appeler les méthodes CopyTo () et Count (). J'ai écrit cette extension pour combler le vide:
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;
}
}
La méthode décode le tableau BitArray en un tableau d'octets à l'aide de la logique LSB (octet moins significatif). C'est la même logique que celle utilisée par la classe BitArray. L'appel de la méthode avec le paramètre MSB défini sur true produira une séquence d'octets décodés MSB. Dans ce cas, rappelez-vous qu'il peut également être nécessaire d'inverser la collection d'octets de sortie finale.
En plus de @JonSkeet answer, vous pouvez utiliser la méthode générique:
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];
}
Et utiliser comme:
BitArray foo = new BitArray(new bool[]
{
false, false, false, false,false, false, false, true
});
foo.ToByte();
Convertisseur de tableau en petits octets endian: Le premier bit (indexé par "0") dans le tableau BitArray Est supposé représenter le bit le moins significatif (le bit le plus à droite de l'octet), interprété comme "zéro" ou "un" comme binaire.
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
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;
}
À votre santé!
Un échantillon de mes codes:
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