Frage

Ich habe ein Array von 128 Boolesche Werte, die Bits repräsentieren. Wie kann ich wandeln diese 128-Bit-Darstellungen in 16 Bytes?

Beispiel:

Ich habe ein Array, das wie folgt aussieht:

0110001100110000100010111011001011010011010001010001101101001100
1000010000000000001000111111111101000011111001111011111011111001

(umgerechnet auf 1 und 0 prägnanter sein)

Ich brauche diese Bits auf die folgenden Byte-Array zu konvertieren:

99 48 139 178 211 69 27 76 132 0 35 255 67 231 190 249

EDIT: Dies scheint nicht zu funktionieren:

public byte[] ToByteArray() {
    int numBytes = Count / 8;

    if (_bits.Count % 8 != 0) numBytes++;

    byte[] bytes = new byte[numBytes];

    int byteIndex = 0, bitIndex = 0;

    for (int i = 0; i < _bits.Count; i++) {
        if (_bits[i])
            bytes[byteIndex] |= (byte)(1 << bitIndex);

        bitIndex++;
        if (bitIndex == 8) {
            bitIndex = 0;
            byteIndex++;
        }
    }

    return bytes;
}

Es gibt:

198 12 209 77 203 162 216 50 33 0 196 255 194 231 125 159
War es hilfreich?

Lösung

Der Code das erste Bit als der Low-Bit des Wortes behandelt, so dass Sie mit jedem Wort umgekehrt enden. Als schnelle und unsaubere fix, versuchen Sie dies:

bytes[byteIndex] |= (byte)(1 << (7-bitIndex));

Das setzt das erste Bit in der Anordnung an der höchsten Stelle im ersten Byte, etc.

Andere Tipps

Ich weiß nicht, ob es eine automatische Art und Weise, es zu tun, aber man kann es mit einem einfachen Algorithmus tun.

Einfacher Algorithmus:

  1. ein Array von Bytes erstellen, die als Ausgabepuffer verwendet wird, und initialisieren alle Bytes auf 0. Die Größe dieses Array auf die Länge Ihrer Eingabe boolean Array basieren sollte: ceil (bool_array_length / 8.0)

  2. eine Indexvariable deklarieren als Ihr aktuelles Byte verwendet werden soll, und setzen Sie ihn auf 0. Damit wird der Index in der Ausgabepuffer hält.

  3. Iterate über jedes Element in Ihrer Eingabe boolean-Array.
    3.1. Links Bit die Nummer 1 durch den Array-Index mod 8. Rufen Sie diese Nummer Maske verschieben.
    3.2. Berechnen Sie Ihre Byte-Index wie der aktuelle Index in das Array div 8.
    3.3. Wenn Sie einen boolean true Wert der aktuellen Index in Ihrer Eingabe boolean-Array haben, führen Sie eine bitwise OR mit Ihrem aktuellen Byte und Maske.

bool[] bools = ...
BitArray a = new BitArray(bools);
byte[] bytes = new byte[a.Length / 8];
a.CopyTo(bytes, 0);

EDIT: Eigentlich ist diese auch zurückgibt:

198 12 209 77 203 162 216 50 33 0 196 255 194 231 125 159

Wrong endianness? Ich lasse jedenfalls als Referenz beantworten.


EDIT: Sie können BitArray.CopyTo () verwenden, indem Sie die Felder wie so Umkehren:

bool[] bools = ...
Array.Reverse(bools); // NOTE: this modifies your original array
BitArray a = new BitArray(bools);
byte[] bytes = new byte[a.Length / 8];
a.CopyTo(bytes, 0);
Array.Reverse(bytes);

Versuchen Sie, diese Funktion (als Erweiterung Methode geschrieben).

public byte[] ToByteArray(this bool[] bits)
{
    var bytes = new byte[bits.Length / 8];
    for (int i = 0, j = 0; j < bits.Length; i++, j += 8)
    {
        // Create byte from bits where LSB is read first.
        for (int offset = 0; offset < 8; offset++)
            bytes[i] |= (bits[j + offset] << offset);
    }

    return bytes;
}

Hinweis: Es wird fehlschlagen, wenn die Anzahl der Bits (bools) nicht ein Vielfaches von 8 ist, aber Ihre Frage zu urteilen ist dies nicht der Fall ist. Es wäre nur eine sehr kleine modificaiton nehmen Bit-Arrays beliebiger Länge zu ermöglichen.

private static byte[] GetBytes(string bitString)
{
    byte[] result = Enumerable.Range(0, bitString.Length / 8).
        Select(pos => Convert.ToByte(
            bitString.Substring(pos * 8, 8),
            2)
        ).ToArray();

    List<byte> mahByteArray = new List<byte>();
    for (int i = result.Length - 1; i >= 0; i--)
    {
        mahByteArray.Add(result[i]);
    }

    return mahByteArray.ToArray();
}

private static String ToBitString(BitArray bits)
{
    var sb = new StringBuilder();

    for (int i = bits.Count - 1; i >= 0; i--)
    {
        char c = bits[i] ? '1' : '0';
        sb.Append(c);
    }

    return sb.ToString();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top