Domanda

Ho un array di 128 booleani che rappresentano bit. Come posso convertire queste rappresentazioni a 128 bit in 16 byte?

Esempio:

Ho una matrice che assomiglia a questo:

0110001100110000100010111011001011010011010001010001101101001100
1000010000000000001000111111111101000011111001111011111011111001

(convertito in 1 e 0 per essere più conciso)

devo convertire quei bit al seguente array di byte:

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

EDIT: Questo non sembra funzionare:

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

E 'uscite:

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

Soluzione

Il codice è trattare il primo bit come il basso bit della parola, così si finisce con ogni parola invertita. Come una soluzione rapida e-sporca, provate questo:

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

che mette il primo bit nella matrice nella posizione più alta nel primo byte, ecc.

Altri suggerimenti

Non so se c'è un modo automatico per farlo, ma lo si può fare con un semplice algoritmo.

algoritmo semplice:

  1. Creare un array di byte che verranno utilizzati come buffer di uscita, e inizializzare tutti i byte a 0. La dimensione di questo array deve essere basata sulla lunghezza della matrice di input booleano: ceil (bool_array_length / 8.0)

  2. Dichiarare una variabile indice per essere utilizzato come byte corrente, e impostarlo a 0. Questo contiene l'indice nel buffer di uscita.

  3. iterare su ogni elemento nella vostra gamma di ingresso booleano.
    3.1. Lasciò po spostare il numero 1 per l'indice dell'array mod 8. chiamare questo numero la maschera.
    3.2. Calcola il tuo indice di byte come l'indice corrente nella matrice div 8.
    3.3. Se si dispone di un valore booleano true l'indice corrente in ingresso matrice booleano, fare un bitwise OR con il byte corrente e la maschera.

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

EDIT: In realtà questo torna anche:

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

endianness sbagliata? Lascio rispondere in ogni caso, per riferimento.


EDIT: È possibile utilizzare BitArray.CopyTo () invertendo le matrici in questo modo:

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

Prova questa funzione (scritto come un metodo di estensione).

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

Nota: fallirà se il numero di bit (Caccio) non è un multiplo di 8, ma a giudicare dalla tua domanda a questo non è il caso. Si sarebbe solo una piccolissima modificaiton per consentire le matrici di bit di qualsiasi lunghezza.

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();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top