Question

I ai un tableau de 128 booléens représentant des bits. Comment puis-je convertir ces 128 représentations de bits en 16 octets?

Exemple:

J'ai un tableau qui ressemble à ceci:

0110001100110000100010111011001011010011010001010001101101001100
1000010000000000001000111111111101000011111001111011111011111001

(converti en 1 et de 0 à être plus concise)

Je dois convertir ces bits au tableau d'octets suivant:

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

EDIT: Cela ne semble pas fonctionner:

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

Il produit:

198 12 209 77 203 162 216 50 33 0 196 255 194 231 125 159
Était-ce utile?

La solution

Le code traite le premier bit comme bit faible du mot, si vous vous retrouvez avec chaque mot inversé. En tant que solution rapide et sale, essayez ceci:

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

Cela met le premier bit dans le tableau à la position la plus élevée dans le premier octet, etc.

Autres conseils

Je ne sais pas s'il y a un moyen automatique de le faire, mais vous pouvez le faire avec un algorithme simple.

algorithme simple:

  1. Créer un tableau d'octets qui seront utilisés comme tampon de sortie, et initialiser tous les octets à 0. La taille de ce tableau doit être basée sur la longueur de votre entrée matrice booléenne: ceil (bool_array_length / 8,0)

  2. Déclarer une variable d'index à utiliser comme octet courant, et le mettre à 0. Cela est l'indice dans votre tampon de sortie.

  3. itérer sur chaque élément dans votre entrée tableau booléen.
    3.1. Gauche bit déplacer le numéro 1 par l'index de tableau mod 8. Composez ce numéro de votre masque.
    3.2. Calculez votre indice d'octets que votre index en cours dans le div tableau 8.
    3.3. Si vous avez une valeur booléenne true l'index courant dans votre entrée tableau booléen, faites un bitwise OR avec votre octet actuel et votre masque.

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

EDIT: En fait, cela renvoie aussi:

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

Mauvais boutisme? Je vais laisser répondre de toute façon, pour référence.


EDIT: Vous pouvez utiliser BitArray.CopyTo () en inversant les tableaux comme ceci:

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

Essayez cette fonction (écrit comme une méthode d'extension).

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

Note: Il échouera si le nombre de bits (bools) n'est pas un multiple de 8, mais à en juger par votre question ce n'est pas le cas. Il ne prendra qu'une très petite modificaiton pour permettre des tableaux de bits de toute longueur.

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();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top