سؤال

انا املك 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);
هل كانت مفيدة؟

المحلول

هذا يجب أن يعمل:

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

نصائح أخرى

وظيفة متأخرة بعض الشيء، ولكن هذا يعمل بالنسبة لي:

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

.

حل رجل فقير:

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

هذا ينبغي أن تفعل خدعة. ومع ذلك، فإن الإجابة السابقة من المحتمل جدا أن يكون الخيار الأفضل.

    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 Coresponds إلى القليل الأول في البايت المرتجع.

هذا يجب أن يكون في نهاية المطاف واحد. يعمل مع أي طول الصفيف.

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;

    }

بالإضافة إلى Jonstkeet الإجابة، يمكنك استخدام طريقة عامة كما ضربة:

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();

لسوء الحظ، يتم تنفيذ فئة Bitarray جزئيا في فئة .NET الأساسية (UWP). على سبيل المثال فئة Bitarray غير قادرة على استدعاء أساليب النسخ () والحول (). كتبت هذا التمديد لملء الفجوة:

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 Set On True سيؤدي إلى إنتاج تسلسل بايت فك التشفير MSB. في هذه الحالة، تذكر أنك قد تحتاج أيضا إلى عكس مجموعة بايت الإخراج النهائية.

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

هتافات!

Little Endian Byte Array Converter: First Bit (مفهرسة مع "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

عينة من رموز بلدي:

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top